testserver/Spigot-Server-Patches/0261-Ignore-Dead-Entities-i...

130 lines
7.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 28 Jul 2018 12:18:27 -0400
Subject: [PATCH] Ignore Dead Entities in entityList iteration
A spigot change delays removal of entities from the entity list.
This causes a change in behavior from Vanilla where getEntities type
methods will return dead entities that they shouldn't otherwise be doing.
This will ensure that dead entities are skipped from iteration since
they shouldn't of been in the list in the first place.
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index b839769ceae8932bb121a0b96fde1e7d129a1f63..5acad8e44f024d3ddf5ef4fd320460ac516e0fb8 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -179,6 +179,7 @@ public class PaperCommand extends Command {
Collection<Entity> entities = world.entitiesById.values();
entities.forEach(e -> {
MinecraftKey key = e.getMinecraftKey();
+ if (e.shouldBeRemoved) return; // Paper
MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 9f369f932ca0a63bde246420cfde7949f3e78ca2..c84d90a9a0c67b5ff518ce3fbc21344c808a3cf1 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -816,6 +816,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
Entity entity1 = (Entity) iterator.next();
+ if (entity1.shouldBeRemoved) continue; // Paper
if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) {
if (predicate == null || predicate.test(entity1)) {
@@ -853,6 +854,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
T entity = (T) iterator.next(); // CraftBukkit - decompile error
+ if (entity.shouldBeRemoved) continue; // Paper
if ((entitytypes == null || entity.getEntityType() == entitytypes) && entity.getBoundingBox().c(axisalignedbb) && predicate.test(entity)) {
list.add(entity);
@@ -874,6 +876,7 @@ public class Chunk implements IChunkAccess {
while (iterator.hasNext()) {
T t0 = (T) iterator.next(); // CraftBukkit - decompile error
+ if (t0.shouldBeRemoved) continue; // Paper
if (oclass.isInstance(t0) && t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) { // Spigot - instance check
list.add(t0);
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 84d36ea84e25a701af22900af6cd3099adf6cd54..6e87ff52df30f4de8cfb11d1dbfb71211d656831 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -195,6 +195,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
protected int numCollisions = 0; // Paper
public void inactiveTick() { }
// Spigot end
+ public boolean shouldBeRemoved; // Paper
public float getBukkitYaw() {
return this.yaw;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 426ca12970e0c75ba75eee6c3e3cdbf833730737..3067ab76d94c58fbfd52fac6754bf6d6d7f01d09 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -908,7 +908,7 @@ public class WorldServer extends World {
while (objectiterator.hasNext()) {
Entity entity = (Entity) objectiterator.next();
-
+ if (entity.shouldBeRemoved) continue; // Paper
if (entity instanceof EntityInsentient) {
EntityInsentient entityinsentient = (EntityInsentient) entity;
@@ -1230,6 +1230,7 @@ public class WorldServer extends World {
entity.origin = entity.getBukkitEntity().getLocation();
}
// Paper end
+ entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added
new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
}
@@ -1242,6 +1243,7 @@ public class WorldServer extends World {
this.removeEntityFromChunk(entity);
this.entitiesById.remove(entity.getId());
this.unregisterEntity(entity);
+ entity.shouldBeRemoved = true; // Paper
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index a59172ff043e5220ffdd363582c38ae53c429f1a..6c3cd51d92d2271cd216c42c18733d549fbe668d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1027,6 +1027,7 @@ public class CraftWorld implements World {
for (Object o : world.entitiesById.values()) {
if (o instanceof net.minecraft.server.Entity) {
net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o;
+ if (mcEnt.shouldBeRemoved) continue; // Paper
Entity bukkitEntity = mcEnt.getBukkitEntity();
// Assuming that bukkitEntity isn't null
@@ -1046,6 +1047,7 @@ public class CraftWorld implements World {
for (Object o : world.entitiesById.values()) {
if (o instanceof net.minecraft.server.Entity) {
net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o;
+ if (mcEnt.shouldBeRemoved) continue; // Paper
Entity bukkitEntity = mcEnt.getBukkitEntity();
// Assuming that bukkitEntity isn't null
@@ -1072,6 +1074,7 @@ public class CraftWorld implements World {
for (Object entity: world.entitiesById.values()) {
if (entity instanceof net.minecraft.server.Entity) {
+ if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper
Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity();
if (bukkitEntity == null) {
@@ -1095,6 +1098,7 @@ public class CraftWorld implements World {
for (Object entity: world.entitiesById.values()) {
if (entity instanceof net.minecraft.server.Entity) {
+ if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper
Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity();
if (bukkitEntity == null) {