Merge branch 'master' into pre/1.13

* master:
  Always process chunk registration after moving
  Always move Entity to its new Chunk even if unloaded
  If Entity is added to chunk, look up the chunk if current isnt set
  Ignore Dead Entities in entityList iteration
  Always process chunk removal in removeEntity
This commit is contained in:
Aikar 2018-07-29 13:12:39 -04:00
commit fc1e70df07
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
5 changed files with 217 additions and 8 deletions

View file

@ -1,4 +1,4 @@
From f4d51258d98a1bb3dbcb677a296fb9d132b6c159 Mon Sep 17 00:00:00 2001
From 8f17d1b7fe35c66af5f943ff9b11461cae458af6 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 4 Jul 2018 02:10:36 -0400
Subject: [PATCH] Store reference to current Chunk for Entity and Block
@ -8,7 +8,7 @@ This enables us a fast reference to the entities current chunk instead
of having to look it up by hashmap lookups.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index cd4fbee0ca..7837f1024c 100644
index cd4fbee0c..7837f1024 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -33,7 +33,7 @@ public class Chunk implements IChunkAccess {
@ -86,9 +86,18 @@ index cd4fbee0ca..7837f1024c 100644
public boolean c(BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 628fda8e7c..17bcef97e0 100644
index aa6230215..701d4a55a 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -133,7 +133,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
private static final DataWatcherObject<Boolean> aF = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
private static final DataWatcherObject<Boolean> aG = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
private static final DataWatcherObject<Boolean> aH = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
- public boolean inChunk;
+ public boolean inChunk; public boolean isAddedToChunk() { return inChunk; } // Paper - OBFHELPER
public int ae; public int getChunkX() { return ae; } // Paper - OBFHELPER
public int af; public int getChunkY() { return af; } // Paper - OBFHELPER
public int ag; public int getChunkZ() { return ag; } // Paper - OBFHELPER
@@ -1782,6 +1782,39 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
@ -103,7 +112,7 @@ index 628fda8e7c..17bcef97e0 100644
+ */
+ public Chunk getCurrentChunk() {
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
+ return chunk != null && chunk.isLoaded() ? chunk : null;
+ return chunk != null && chunk.isLoaded() ? chunk : (isAddedToChunk() ? world.getChunkIfLoaded(getChunkX(), getChunkZ()) : null);
+ }
+ /**
+ * Returns the chunk at the location, using the entities local cache if avail
@ -130,7 +139,7 @@ index 628fda8e7c..17bcef97e0 100644
private String entityKeyString;
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 5ca7fef518..9361667c3b 100644
index 5ca7fef51..9361667c3 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -41,6 +41,15 @@ public abstract class TileEntity implements KeyedObject { // Paper
@ -150,7 +159,7 @@ index 5ca7fef518..9361667c3b 100644
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 72164e11af..f09251eec8 100644
index 72164e11a..f09251eec 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -9,6 +9,7 @@ import java.util.UUID;

View file

@ -1,4 +1,4 @@
From 4187997e2e34556a257a9eb5161104f2f5bec416 Mon Sep 17 00:00:00 2001
From c77ae6f712e3d8402a0aafe3e543cae5b24754d9 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 21 Sep 2016 22:54:28 -0400
Subject: [PATCH] Chunk registration fixes
@ -8,7 +8,7 @@ World checks and the Chunk Add logic are inconsistent on how Y > 256, < 0, is tr
Keep them consistent
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e74b53c48..20e52fbcc 100644
index e74b53c48..01041ede9 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1485,7 +1485,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
@ -20,6 +20,15 @@ index e74b53c48..20e52fbcc 100644
int k = MathHelper.floor(entity.locZ / 16.0D);
if (!entity.inChunk || entity.ae != i || entity.af != j || entity.ag != k) {
@@ -1493,7 +1493,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
this.getChunkAt(entity.ae, entity.ag).a(entity, entity.af);
}
- if (!entity.bN() && !this.isChunkLoaded(i, k, true)) {
+ if (false && !entity.bN() && !this.isChunkLoaded(i, k, true)) { // Paper - Always send entities into a new chunk, never lose them
entity.inChunk = false;
} else {
this.getChunkAt(i, k).a(entity);
--
2.18.0

View file

@ -0,0 +1,33 @@
From c461973839a211b635e7b8446d8acc317726398f Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 28 Jul 2018 12:09:20 -0400
Subject: [PATCH] Always process chunk removal in removeEntity
Spigot might skip chunk registration changes in removeEntity
which can keep them in the chunk when they shouldnt be if done
during entity ticking.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 89d0127af..f8458a2b4 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1134,7 +1134,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
this.everyoneSleeping();
}
- if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking
+ // if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - move down
int i = entity.ae;
int j = entity.ag;
@@ -1142,6 +1142,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
this.getChunkAt(i, j).b(entity);
}
+ 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
int index = this.entityList.indexOf(entity);
if (index != -1) {
--
2.18.0

View file

@ -0,0 +1,103 @@
From e45fe59859d3c44a5175828b4c1727227265bc84 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 7ff8e70b2..4e854c6db 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -172,6 +172,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 80955199e..3a4c9a02e 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 f8458a2b4..ece187129 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1141,6 +1141,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
if (entity.inChunk && this.isChunkLoaded(i, j, true)) {
this.getChunkAt(i, j).b(entity);
}
+ 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
@@ -2348,6 +2349,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
+ if (entity.shouldBeRemoved) continue; // Paper
if (oclass.isAssignableFrom(entity.getClass()) && predicate.test((T) entity)) {
arraylist.add(entity);
@@ -2434,6 +2436,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
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 f4dc7e4ac..8923df898 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -660,6 +660,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
@@ -678,6 +679,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
@@ -702,6 +704,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) {
@@ -724,6 +727,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.18.0

View file

@ -0,0 +1,55 @@
From 82f4d6d15006e4980cee1d2645bf24c35c0c23d2 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 29 Jul 2018 11:58:05 -0400
Subject: [PATCH] Always process chunk registration after moving
This will help guarantee that entities are always in the
chunk that they are currently located at.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 3a4c9a02e..c8f32a49a 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -338,6 +338,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.locX = d0;
this.locY = d1;
this.locZ = d2;
+ if (valid) world.entityJoinedWorld(this, false); // Paper - ensure Entity is moved to its proper chunk
float f = this.width / 2.0F;
float f1 = this.length;
@@ -956,6 +957,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.locX = (axisalignedbb.a + axisalignedbb.d) / 2.0D;
this.locY = axisalignedbb.b;
this.locZ = (axisalignedbb.c + axisalignedbb.f) / 2.0D;
+ if (valid) world.entityJoinedWorld(this, false); // Paper - ensure Entity is moved to its proper chunk
}
protected SoundEffect ad() {
diff --git a/src/main/java/net/minecraft/server/EntityLeash.java b/src/main/java/net/minecraft/server/EntityLeash.java
index f2d3d0b4c..f20060614 100644
--- a/src/main/java/net/minecraft/server/EntityLeash.java
+++ b/src/main/java/net/minecraft/server/EntityLeash.java
@@ -31,6 +31,7 @@ public class EntityLeash extends EntityHanging {
this.locX = (double) this.blockPosition.getX() + 0.5D;
this.locY = (double) this.blockPosition.getY() + 0.5D;
this.locZ = (double) this.blockPosition.getZ() + 0.5D;
+ if (valid) world.entityJoinedWorld(this, false); // Paper - ensure Entity is moved to its proper chunk
}
public void setDirection(EnumDirection enumdirection) {}
diff --git a/src/main/java/net/minecraft/server/EntityShulker.java b/src/main/java/net/minecraft/server/EntityShulker.java
index 95c6cd897..bc11e7da2 100644
--- a/src/main/java/net/minecraft/server/EntityShulker.java
+++ b/src/main/java/net/minecraft/server/EntityShulker.java
@@ -385,6 +385,7 @@ public class EntityShulker extends EntityGolem implements IMonster {
this.locX = (double) blockposition.getX() + 0.5D;
this.locY = (double) blockposition.getY();
this.locZ = (double) blockposition.getZ() + 0.5D;
+ if (valid) world.entityJoinedWorld(this, false); // Paper - ensure Entity is moved to its proper chunk
this.lastX = this.locX;
this.lastY = this.locY;
this.lastZ = this.locZ;
--
2.18.0