Strengthen entity list guard patch back up to its original level. Whilst upstream fixes attempt to fix this, they aren't fully functional and can cause the server to crash. This way we can both identify bad plugins and stop all crashes.
This commit is contained in:
parent
6ed812be08
commit
71fce21cdd
|
@ -0,0 +1,79 @@
|
||||||
|
From 71dc389b977238a15bb2a1aa44670aa12a6513a6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: md_5 <git@md-5.net>
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
index 6ec7f5a..9bc4256 100644
|
||||||
--- a/src/main/java/net/minecraft/server/World.java
|
--- a/src/main/java/net/minecraft/server/World.java
|
||||||
+++ b/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 abstract class World implements IBlockAccess {
|
||||||
|
|
||||||
public boolean d;
|
public boolean d;
|
||||||
|
@ -35,51 +35,39 @@ index 6ec7f5a..9bc4256 100644
|
||||||
protected List f = new ArrayList();
|
protected List f = new ArrayList();
|
||||||
public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet
|
public Set tileEntityList = new HashSet(); // CraftBukkit - ArrayList -> HashSet
|
||||||
private List a = new ArrayList();
|
private List a = new ArrayList();
|
||||||
@@ -78,6 +96,7 @@ public abstract class World implements IBlockAccess {
|
@@ -74,6 +92,7 @@ public abstract class World implements IBlockAccess {
|
||||||
int[] I;
|
int[] H;
|
||||||
|
public boolean isStatic;
|
||||||
// Spigot start
|
// Spigot start
|
||||||
+ private boolean guardEntityList = false;
|
+ private boolean guardEntityList;
|
||||||
protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList;
|
protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList;
|
||||||
protected float growthOdds = 100;
|
protected float growthOdds = 100;
|
||||||
protected float modifiedOdds = 100;
|
protected float modifiedOdds = 100;
|
||||||
@@ -1033,7 +1052,12 @@ public abstract class World implements IBlockAccess {
|
@@ -1285,6 +1304,7 @@ 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 {
|
|
||||||
|
|
||||||
org.spigotmc.ActivationRange.activateEntities(this); // Spigot
|
org.spigotmc.ActivationRange.activateEntities(this); // Spigot
|
||||||
timings.entityTick.startTiming(); // Spigot
|
timings.entityTick.startTiming(); // Spigot
|
||||||
+ guardEntityList = true; // Spigot
|
+ guardEntityList = true; // Spigot
|
||||||
// CraftBukkit start - Use field for loop variable
|
for (i = 0; i < this.entityList.size(); ++i) {
|
||||||
for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) {
|
entity = (Entity) this.entityList.get(i);
|
||||||
entity = (Entity) this.entityList.get(this.tickPosition);
|
|
||||||
@@ -1320,12 +1345,15 @@ public abstract class World implements IBlockAccess {
|
@@ -1331,14 +1351,16 @@ public abstract class World implements IBlockAccess {
|
||||||
|
if (entity.ai && this.isChunkLoaded(j, k)) {
|
||||||
this.getChunkAt(j, k).b(entity);
|
this.getChunkAt(j, k).b(entity);
|
||||||
}
|
}
|
||||||
|
-
|
||||||
+ guardEntityList = false; // Spigot
|
+ guardEntityList = false; // Spigot
|
||||||
this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable
|
this.entityList.remove(i--);
|
||||||
+ guardEntityList = true; // Spigot
|
+ guardEntityList = true; // Spigot
|
||||||
this.b(entity);
|
this.b(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.methodProfiler.b();
|
this.methodProfiler.b();
|
||||||
}
|
}
|
||||||
|
lastChunk = Long.MIN_VALUE; // Spigot
|
||||||
+ guardEntityList = false; // Spigot
|
+ guardEntityList = false; // Spigot
|
||||||
|
|
||||||
timings.entityTick.stopTiming(); // Spigot
|
timings.entityTick.stopTiming(); // Spigot
|
||||||
this.methodProfiler.c("blockEntities");
|
this.methodProfiler.c("tileEntities");
|
||||||
--
|
--
|
||||||
1.8.3.2
|
1.8.1.msysgit.1
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue