aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0307-Ignore-Dead-Entities-in-entityList-iteration.patch
blob: e2420f1763029f85c99ac5ff95089e47daf9c941 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
From d56b8e342642b04ba0e3d1aa97ad38442f621c95 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 f38179e98..8e1bda4de 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -176,6 +176,7 @@ public class PaperCommand extends Command {
                 List<Entity> entities = world.entityList;
                 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/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index ead5af991..cf69a4d8a 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -121,6 +121,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
     protected boolean F;
     private boolean az;
     public boolean dead;
+    public boolean shouldBeRemoved; // Paper
     public float width;
     public float length;
     public float J;
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e2068c33f..c32fb50f1 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1046,6 +1046,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
         }
 
         entity.valid = true; // CraftBukkit
+        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
     }
 
@@ -1113,6 +1114,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
 
         Chunk chunk = entity.getCurrentChunk(); // Paper
         if (chunk != null) chunk.removeEntity(entity); // Paper
+        entity.shouldBeRemoved = true; // Paper
 
         if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above
         // CraftBukkit start - Decrement loop variable field if we've already ticked this entity
@@ -2315,6 +2317,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
 
         while (iterator.hasNext()) {
             Entity entity = (Entity) iterator.next();
+            if (entity.shouldBeRemoved) continue; // Paper
 
             if (oclass.isAssignableFrom(entity.getClass()) && predicate.test((T) entity)) { // CraftBukkit - decompile error
                 list.add((T) entity); // CraftBukkit - decompile error
@@ -2401,6 +2404,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
 
         while (iterator.hasNext()) {
             Entity entity = (Entity) iterator.next();
+            if (entity.shouldBeRemoved) continue; // Paper
             // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs
             if (entity instanceof EntityInsentient) {
                 EntityInsentient entityinsentient = (EntityInsentient) entity;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 609b91126..4594bab46 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -634,6 +634,7 @@ public class CraftWorld implements World {
         for (Object o : world.entityList) {
             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
@@ -652,6 +653,7 @@ public class CraftWorld implements World {
         for (Object o : world.entityList) {
             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
@@ -676,6 +678,7 @@ public class CraftWorld implements World {
 
         for (Object entity: world.entityList) {
             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) {
@@ -698,6 +701,7 @@ public class CraftWorld implements World {
 
         for (Object entity: world.entityList) {
             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) {
-- 
2.21.0