diff --git a/Spigot-Server-Patches/0033-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch b/Spigot-Server-Patches/0032-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch similarity index 93% rename from Spigot-Server-Patches/0033-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch rename to Spigot-Server-Patches/0032-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch index 8fdf3a1d9c..9fd04faf95 100644 --- a/Spigot-Server-Patches/0033-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch +++ b/Spigot-Server-Patches/0032-Show-PaperSpigot-in-client-crashes-server-lists-and-.patch @@ -1,4 +1,4 @@ -From 5f45ba374861f6f602851e837532c86ce8b018f0 Mon Sep 17 00:00:00 2001 +From 593eb666fbbc94ad31d0fa8edc1b396609c57817 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 19 Aug 2014 14:21:37 -0500 Subject: [PATCH] Show 'PaperSpigot' in client crashes, server lists, and diff --git a/Spigot-Server-Patches/0034-RIP-metrics.patch b/Spigot-Server-Patches/0033-RIP-metrics.patch similarity index 99% rename from Spigot-Server-Patches/0034-RIP-metrics.patch rename to Spigot-Server-Patches/0033-RIP-metrics.patch index 0d99173b5e..e3db0a4c73 100644 --- a/Spigot-Server-Patches/0034-RIP-metrics.patch +++ b/Spigot-Server-Patches/0033-RIP-metrics.patch @@ -1,4 +1,4 @@ -From b3dda52207845877ca74ff77188345c8e9f150af Mon Sep 17 00:00:00 2001 +From 8054c4bd0e8f23cb928f3668364a3a356e6c600b Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 19 Aug 2014 14:25:40 -0500 Subject: [PATCH] RIP metrics @@ -657,7 +657,7 @@ index d9c3b63..0000000 -} \ No newline at end of file diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java -index fdc64d3..414f8c1 100644 +index 919c83c..3b43e0f 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -48,7 +48,6 @@ public class SpigotConfig diff --git a/Spigot-Server-Patches/0035-Remove-invalid-mob-spawner-tile-entities.patch b/Spigot-Server-Patches/0034-Remove-invalid-mob-spawner-tile-entities.patch similarity index 96% rename from Spigot-Server-Patches/0035-Remove-invalid-mob-spawner-tile-entities.patch rename to Spigot-Server-Patches/0034-Remove-invalid-mob-spawner-tile-entities.patch index fd192ea242..8ab7491a64 100644 --- a/Spigot-Server-Patches/0035-Remove-invalid-mob-spawner-tile-entities.patch +++ b/Spigot-Server-Patches/0034-Remove-invalid-mob-spawner-tile-entities.patch @@ -1,4 +1,4 @@ -From 7e400c3c9715fb60b454dcdbe26762a5ff344839 Mon Sep 17 00:00:00 2001 +From 26a71dce3043888ddf32b404a9e01d11513b9e79 Mon Sep 17 00:00:00 2001 From: Byteflux Date: Tue, 19 Aug 2014 14:51:28 -0500 Subject: [PATCH] Remove invalid mob spawner tile entities diff --git a/Spigot-Server-Patches/0035-Optimize-TileEntity-Ticking.patch b/Spigot-Server-Patches/0035-Optimize-TileEntity-Ticking.patch new file mode 100644 index 0000000000..442a47249a --- /dev/null +++ b/Spigot-Server-Patches/0035-Optimize-TileEntity-Ticking.patch @@ -0,0 +1,285 @@ +From 6e7a139066c3fd9fa5274045d80aede527b636ab Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sun, 24 Aug 2014 21:35:11 -0400 +Subject: [PATCH] Optimize TileEntity Ticking + +Re-organizes the servers TileEntity Tick List to be bucketed based on their tick interval. + +We now will not even store a Tile Entity that is known to not have any tick function +(half of them), skipping time spent iterating them and checking if they are valid +and in a loaded chunk. In other words, a lot of "meta" time wasted on tile entities +that would never do anything anyways. + +Then by reducing chests to 1 in 20 ticks, we cut out 95% of isLoaded checks and findPlayer +calls on chests, and 100% of the checks for Signs, the 2 most popular Tile Entities. + +This cuts out a massive amount of checks revolving around TileEntity ticking. +Servers with large amounts of TileEntities should see significant improvement. + +Finally, this then spreads out the ticking of reduced-rate TileEntities so that they +do not all tick on the same tick, distributing the load of some TileEntities like Chest. + +diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java +index 3c5ec6f..27fedeb 100644 +--- a/src/main/java/net/minecraft/server/TileEntity.java ++++ b/src/main/java/net/minecraft/server/TileEntity.java +@@ -56,6 +56,12 @@ public class TileEntity { + } + } + } ++ ++ // Optimized TileEntity Tick changes ++ private static int tileEntityCounter = 0; ++ public boolean isAdded = false; ++ public int tileId = tileEntityCounter++; ++ + // Spigot end + + public TileEntity() {} +diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java +index 09313ea..198f908 100644 +--- a/src/main/java/net/minecraft/server/TileEntityBeacon.java ++++ b/src/main/java/net/minecraft/server/TileEntityBeacon.java +@@ -45,7 +45,7 @@ public class TileEntityBeacon extends TileEntity implements IInventory { + public TileEntityBeacon() {} + + public void h() { +- if (this.world.getTime() % 80L == 0L) { ++ if (true || this.world.getTime() % 80L == 0L) { // PaperSpigot - controlled by Improved Tick handling + this.y(); + this.x(); + } +diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java +index c900caf..e27716b 100644 +--- a/src/main/java/net/minecraft/server/TileEntityChest.java ++++ b/src/main/java/net/minecraft/server/TileEntityChest.java +@@ -255,7 +255,7 @@ public class TileEntityChest extends TileEntity implements IInventory { + ++this.ticks; + float f; + +- if (!this.world.isStatic && this.o != 0 && (this.ticks + this.x + this.y + this.z) % 200 == 0) { ++ if (!this.world.isStatic && this.o != 0 && (this.ticks + this.x + this.y + this.z) % 10 == 0) { // PaperSpigot Reduced 200 -> 10 interval due to reduced tick rate from Improved Tick Handling + this.o = 0; + f = 5.0F; + List list = this.world.a(EntityHuman.class, AxisAlignedBB.a((double) ((float) this.x - f), (double) ((float) this.y - f), (double) ((float) this.z - f), (double) ((float) (this.x + 1) + f), (double) ((float) (this.y + 1) + f), (double) ((float) (this.z + 1) + f))); +diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java +index b205ab7..d76a2b2 100644 +--- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java ++++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java +@@ -11,7 +11,7 @@ public class TileEntityEnderChest extends TileEntity { + + public void h() { + super.h(); +- if (++this.k % 20 * 4 == 0) { ++ if (++this.k % 4 == 0) { // PaperSpigot Reduced (20 * 4) -> 4 interval due to reduced tick rate from Improved Tick Handling + this.world.playBlockAction(this.x, this.y, this.z, Blocks.ENDER_CHEST, 1, this.j); + } + +diff --git a/src/main/java/net/minecraft/server/TileEntityLightDetector.java b/src/main/java/net/minecraft/server/TileEntityLightDetector.java +index 143cffb..de33df0 100644 +--- a/src/main/java/net/minecraft/server/TileEntityLightDetector.java ++++ b/src/main/java/net/minecraft/server/TileEntityLightDetector.java +@@ -5,7 +5,7 @@ public class TileEntityLightDetector extends TileEntity { + public TileEntityLightDetector() {} + + public void h() { +- if (this.world != null && !this.world.isStatic && this.world.getTime() % 20L == 0L) { ++ if (this.world != null && !this.world.isStatic /*&& this.world.getTime() % 20L == 0L*/) { // PaperSpigot - interval controlled by Improved Tick Handling + this.h = this.q(); + if (this.h instanceof BlockDaylightDetector) { + ((BlockDaylightDetector) this.h).e(this.world, this.x, this.y, this.z); +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 33c228b..3bf2af0 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -58,7 +58,7 @@ public abstract class World implements IBlockAccess { + }; + // Spigot end + protected List f = new ArrayList(); +- public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet ++ public Set tileEntityList = new org.spigotmc.WorldTileEntityList(this); // CraftBukkit - ArrayList -> HashSet + private List a = new ArrayList(); + private List b = new ArrayList(); + public List players = new ArrayList(); +diff --git a/src/main/java/org/spigotmc/WorldTileEntityList.java b/src/main/java/org/spigotmc/WorldTileEntityList.java +new file mode 100644 +index 0000000..4e6b762 +--- /dev/null ++++ b/src/main/java/org/spigotmc/WorldTileEntityList.java +@@ -0,0 +1,173 @@ ++package org.spigotmc; ++ ++import com.google.common.collect.ArrayListMultimap; ++import com.google.common.collect.Maps; ++import com.google.common.collect.Multimap; ++import net.minecraft.server.*; ++import net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap; ++ ++import java.util.Collection; ++import java.util.HashSet; ++import java.util.Iterator; ++import java.util.Map; ++ ++public class WorldTileEntityList extends HashSet { ++ private static final TObjectIntHashMap> tileEntityTickIntervals = ++ new TObjectIntHashMap>() {{ ++ // Use -1 for no ticking ++ // These TE's have empty tick methods, doing nothing. Never bother ticking them. ++ for (Class ignored : new Class[]{ ++ TileEntityChest.class, // PaperSpigot - Don't tick chests either ++ TileEntityEnderChest.class, // PaperSpigot - Don't tick chests either ++ TileEntityRecordPlayer.class, ++ TileEntityDispenser.class, ++ TileEntityDropper.class, ++ TileEntitySign.class, ++ TileEntityNote.class, ++ TileEntityEnderPortal.class, ++ TileEntityCommand.class, ++ TileEntitySkull.class, ++ TileEntityComparator.class, ++ TileEntityFlowerPot.class ++ }) { ++ put(ignored, -1); ++ } ++ ++ // does findPlayer lookup, so this helps performance to slow down ++ put(TileEntityEnchantTable.class, 20); ++ ++ // Slow things down that players won't notice due to craftbukkit "wall time" patches. ++ put(TileEntityFurnace.class, 10); ++ put(TileEntityBrewingStand.class, 10); ++ ++ // Vanilla controlled values - These are checks already done in vanilla, so don't tick on ticks we know ++ // won't do anything anyways ++ put(TileEntityBeacon.class, 80); ++ put(TileEntityLightDetector.class, 20); ++ }}; ++ private static int getInterval(Class cls) { ++ int tickInterval = tileEntityTickIntervals.get(cls); ++ return tickInterval != 0 ? tickInterval : 1; ++ } ++ ++ private static int getBucketId(TileEntity entity, Integer interval) { ++ return entity.tileId % interval; ++ } ++ ++ private final Map> tickList = Maps.newHashMap(); ++ private final WorldServer world; ++ ++ public WorldTileEntityList(World world) { ++ this.world = (WorldServer) world; ++ } ++ ++ ++ private Multimap getBucket(int interval) { ++ Multimap intervalBucket = tickList.get(interval); ++ if (intervalBucket == null) { ++ intervalBucket = ArrayListMultimap.create(); ++ tickList.put(interval, intervalBucket); ++ } ++ return intervalBucket; ++ } ++ ++ /** ++ * Adds the TileEntity to the tick list only if it is expected to tick ++ */ ++ @Override ++ public boolean add(TileEntity entity) { ++ if (entity.isAdded) { ++ return false; ++ } ++ ++ int interval = getInterval(entity.getClass()); ++ if (interval > 0) { ++ entity.isAdded = true; ++ int bucket = getBucketId(entity, interval); ++ Multimap typeBucket = getBucket(interval); ++ return typeBucket.put(bucket, entity); ++ } ++ return false; ++ } ++ ++ @Override ++ public boolean remove(Object o) { ++ if (!(o instanceof TileEntity)) { ++ return false; ++ } ++ TileEntity entity = (TileEntity) o; ++ if (!entity.isAdded) { ++ return false; ++ } ++ entity.isAdded = false; ++ int interval = getInterval(entity.getClass()); ++ int bucket = getBucketId(entity, interval); ++ Multimap typeBucket = getBucket(interval); ++ return typeBucket.remove(bucket, entity); ++ } ++ ++ @Override ++ public Iterator iterator() { ++ return new WorldTileEntityIterator(); ++ } ++ ++ @Override ++ public boolean contains(Object o) { ++ return o instanceof TileEntity && ((TileEntity) o).isAdded; ++ } ++ ++ private class WorldTileEntityIterator implements Iterator { ++ private final Iterator>> intervalIterator; ++ private Map.Entry> intervalMap = null; ++ private Iterator listIterator = null; ++ ++ protected WorldTileEntityIterator() { ++ intervalIterator = tickList.entrySet().iterator(); ++ nextInterval(); ++ } ++ ++ private boolean nextInterval() { ++ listIterator = null; ++ if (intervalIterator.hasNext()) { ++ intervalMap = intervalIterator.next(); ++ ++ final Integer interval = intervalMap.getKey(); ++ final Multimap buckets = intervalMap.getValue(); ++ ++ int bucket = (int) (world.getTime() % interval); ++ ++ if (!buckets.isEmpty() && buckets.containsKey(bucket)) { ++ final Collection tileList = buckets.get(bucket); ++ ++ if (tileList != null && !tileList.isEmpty()) { ++ listIterator = tileList.iterator(); ++ return true; ++ } ++ } ++ } ++ ++ return false; ++ ++ } ++ ++ @Override ++ public boolean hasNext() { ++ do { ++ if (listIterator != null && listIterator.hasNext()) { ++ return true; ++ } ++ } while (nextInterval()); ++ return false; ++ } ++ ++ @Override ++ public TileEntity next() { ++ return listIterator.next(); ++ } ++ ++ @Override ++ public void remove() { ++ listIterator.remove(); ++ } ++ } ++} +-- +1.9.1 + diff --git a/Spigot-Server-Patches/0032-Don-t-tick-chests.patch b/Spigot-Server-Patches/0036-Move-sound-handling-out-of-the-chest-tick-loop.patch similarity index 79% rename from Spigot-Server-Patches/0032-Don-t-tick-chests.patch rename to Spigot-Server-Patches/0036-Move-sound-handling-out-of-the-chest-tick-loop.patch index be6aba5555..34ebf7bdc0 100644 --- a/Spigot-Server-Patches/0032-Don-t-tick-chests.patch +++ b/Spigot-Server-Patches/0036-Move-sound-handling-out-of-the-chest-tick-loop.patch @@ -1,23 +1,26 @@ -From 662acf6926a1381394de4cf4e79540092912c20e Mon Sep 17 00:00:00 2001 +From 459bd528d5385f71580b40a3cd894c1bd8197520 Mon Sep 17 00:00:00 2001 From: Iceee -Date: Fri, 11 Jul 2014 01:31:43 -0500 -Subject: [PATCH] Don't tick chests +Date: Mon, 11 Aug 2014 23:03:47 -0500 +Subject: [PATCH] Move sound handling out of the chest tick loop +This allows us to disable ticking chests and enderchests without any +noticeable difference to players diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java -index c900caf..19eff35 100644 +index e27716b..69ffd30 100644 --- a/src/main/java/net/minecraft/server/TileEntityChest.java +++ b/src/main/java/net/minecraft/server/TileEntityChest.java -@@ -249,6 +249,8 @@ public class TileEntityChest extends TileEntity implements IInventory { - } +@@ -275,6 +275,9 @@ public class TileEntityChest extends TileEntity implements IInventory { + } - public void h() { -+ // PaperSpigot start - Ixnay on the Chest tick-ay + this.n = this.m; ++ ++ // PaperSpigot start - Move chest sound handling out of the tick loop + /* - super.h(); - if (this.world == null) return; // CraftBukkit - this.i(); -@@ -327,6 +329,8 @@ public class TileEntityChest extends TileEntity implements IInventory { + f = 0.1F; + double d0; + +@@ -327,6 +330,8 @@ public class TileEntityChest extends TileEntity implements IInventory { this.m = 0.0F; } } @@ -26,11 +29,11 @@ index c900caf..19eff35 100644 } public boolean c(int i, int j) { -@@ -349,6 +353,26 @@ public class TileEntityChest extends TileEntity implements IInventory { +@@ -349,6 +354,26 @@ public class TileEntityChest extends TileEntity implements IInventory { if (this.world == null) return; // CraftBukkit this.world.playBlockAction(this.x, this.y, this.z, this.q(), 1, this.o); -+ // PaperSpigot start - Move chest open sound handling down here ++ // PaperSpigot start - Move chest open sound handling down to here + this.i(); + double d0; + @@ -53,11 +56,11 @@ index c900caf..19eff35 100644 // CraftBukkit start - Call redstone event if (this.q() == Blocks.TRAPPED_CHEST) { int newPower = Math.max(0, Math.min(15, this.o)); -@@ -371,6 +395,26 @@ public class TileEntityChest extends TileEntity implements IInventory { +@@ -371,6 +396,26 @@ public class TileEntityChest extends TileEntity implements IInventory { if (this.world == null) return; // CraftBukkit this.world.playBlockAction(this.x, this.y, this.z, this.q(), 1, this.o); -+ // PaperSpigot start - Move chest close sound handling down here ++ // PaperSpigot start - Move chest close sound handling down to here + this.i(); + double d0; + @@ -81,19 +84,20 @@ index c900caf..19eff35 100644 if (this.q() == Blocks.TRAPPED_CHEST) { int newPower = Math.max(0, Math.min(15, this.o)); diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java -index b205ab7..158f2e0 100644 +index d76a2b2..339e133 100644 --- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java +++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java -@@ -10,6 +10,8 @@ public class TileEntityEnderChest extends TileEntity { - public TileEntityEnderChest() {} +@@ -16,6 +16,9 @@ public class TileEntityEnderChest extends TileEntity { + } - public void h() { -+ // PaperSpigot start - Ixnay on the EnderChest tick-ay + this.i = this.a; ++ ++ // PaperSpigot start - Move chest sound handling out of the tick loop + /* - super.h(); - if (++this.k % 20 * 4 == 0) { - this.world.playBlockAction(this.x, this.y, this.z, Blocks.ENDER_CHEST, 1, this.j); -@@ -52,6 +54,8 @@ public class TileEntityEnderChest extends TileEntity { + float f = 0.1F; + double d0; + +@@ -52,6 +55,8 @@ public class TileEntityEnderChest extends TileEntity { this.a = 0.0F; } } @@ -102,7 +106,7 @@ index b205ab7..158f2e0 100644 } public boolean c(int i, int j) { -@@ -71,11 +75,39 @@ public class TileEntityEnderChest extends TileEntity { +@@ -71,11 +76,39 @@ public class TileEntityEnderChest extends TileEntity { public void a() { ++this.j; this.world.playBlockAction(this.x, this.y, this.z, Blocks.ENDER_CHEST, 1, this.j);