diff --git a/CraftBukkit-Patches/0115-Guard-Entity-List.patch b/CraftBukkit-Patches/0115-Guard-Entity-List.patch new file mode 100644 index 0000000000..d459e32881 --- /dev/null +++ b/CraftBukkit-Patches/0115-Guard-Entity-List.patch @@ -0,0 +1,79 @@ +From 71dc389b977238a15bb2a1aa44670aa12a6513a6 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Mon, 10 Mar 2014 09:03:28 +1100 +Subject: [PATCH] Guard Entity List + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 6ec7f5a..d0d9ea9 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -29,7 +29,32 @@ import org.bukkit.event.weather.ThunderChangeEvent; + public abstract class World implements IBlockAccess { + + public boolean d; +- public List entityList = new ArrayList(); ++ // Spigot start - guard entity list from removals ++ public List entityList = new ArrayList() ++ { ++ @Override ++ public Object remove(int index) ++ { ++ guard(); ++ return super.remove( index ); ++ } ++ ++ @Override ++ public boolean remove(Object o) ++ { ++ guard(); ++ return super.remove( o ); ++ } ++ ++ private void guard() ++ { ++ if ( guardEntityList ) ++ { ++ throw new java.util.ConcurrentModificationException(); ++ } ++ } ++ }; ++ // Spigot end + protected List f = new ArrayList(); + public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet + private List a = new ArrayList(); +@@ -78,6 +103,7 @@ public abstract class World implements IBlockAccess { + int[] I; + + // Spigot start ++ private boolean guardEntityList; + protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList; + protected float growthOdds = 100; + protected float modifiedOdds = 100; +@@ -1272,6 +1298,7 @@ public abstract class World implements IBlockAccess { + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot ++ guardEntityList = true; // Spigot + // CraftBukkit start - Use field for loop variable + for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { + entity = (Entity) this.entityList.get(this.tickPosition); +@@ -1320,12 +1347,15 @@ public abstract class World implements IBlockAccess { + this.getChunkAt(j, k).b(entity); + } + ++ guardEntityList = false; // Spigot + this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable ++ guardEntityList = true; // Spigot + this.b(entity); + } + + this.methodProfiler.b(); + } ++ guardEntityList = false; // Spigot + + timings.entityTick.stopTiming(); // Spigot + this.methodProfiler.c("blockEntities"); +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0115-Guard-entity-list.patch b/CraftBukkit-Patches/0115-Guard-entity-list.patch index 3a706f46d4..6f7d7dd85c 100644 --- a/CraftBukkit-Patches/0115-Guard-entity-list.patch +++ b/CraftBukkit-Patches/0115-Guard-entity-list.patch @@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/m index 6ec7f5a..9bc4256 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java -@@ -29,7 +29,25 @@ import org.bukkit.event.weather.ThunderChangeEvent; +@@ -29,7 +29,25 @@ import java.util.concurrent.Callable; public abstract class World implements IBlockAccess { public boolean d; @@ -35,51 +35,39 @@ index 6ec7f5a..9bc4256 100644 protected List f = new ArrayList(); public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet private List a = new ArrayList(); -@@ -78,6 +96,7 @@ public abstract class World implements IBlockAccess { - int[] I; - +@@ -74,6 +92,7 @@ public abstract class World implements IBlockAccess { + int[] H; + public boolean isStatic; // Spigot start -+ private boolean guardEntityList = false; ++ private boolean guardEntityList; protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList; protected float growthOdds = 100; protected float modifiedOdds = 100; -@@ -1033,7 +1052,12 @@ public abstract class World implements IBlockAccess { - if (index <= this.tickPosition) { - this.tickPosition--; - } -+ // Spigot start -+ boolean isGuarding = guardEntityList; -+ guardEntityList = false; - this.entityList.remove(index); -+ guardEntityList = isGuarding; -+ // Spigot end - } - // CraftBukkit end - -@@ -1272,6 +1296,7 @@ public abstract class World implements IBlockAccess { +@@ -1285,6 +1304,7 @@ public abstract class World implements IBlockAccess { org.spigotmc.ActivationRange.activateEntities(this); // Spigot timings.entityTick.startTiming(); // Spigot + guardEntityList = true; // Spigot - // CraftBukkit start - Use field for loop variable - for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { - entity = (Entity) this.entityList.get(this.tickPosition); -@@ -1320,12 +1345,15 @@ public abstract class World implements IBlockAccess { + for (i = 0; i < this.entityList.size(); ++i) { + entity = (Entity) this.entityList.get(i); + +@@ -1331,14 +1351,16 @@ public abstract class World implements IBlockAccess { + if (entity.ai && this.isChunkLoaded(j, k)) { this.getChunkAt(j, k).b(entity); } - +- + guardEntityList = false; // Spigot - this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable + this.entityList.remove(i--); + guardEntityList = true; // Spigot this.b(entity); } this.methodProfiler.b(); } + lastChunk = Long.MIN_VALUE; // Spigot + guardEntityList = false; // Spigot timings.entityTick.stopTiming(); // Spigot - this.methodProfiler.c("blockEntities"); + this.methodProfiler.c("tileEntities"); -- -1.8.3.2 - +1.8.1.msysgit.1