diff --git a/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch b/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch index 431700727f..16c97e0eaa 100644 --- a/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch +++ b/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch @@ -1,4 +1,4 @@ -From f4d51258d98a1bb3dbcb677a296fb9d132b6c159 Mon Sep 17 00:00:00 2001 +From 8f17d1b7fe35c66af5f943ff9b11461cae458af6 Mon Sep 17 00:00:00 2001 From: Aikar 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 aF = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + private static final DataWatcherObject aG = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + private static final DataWatcherObject 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; diff --git a/Spigot-Server-Patches/0139-Chunk-registration-fixes.patch b/Spigot-Server-Patches/0139-Chunk-registration-fixes.patch index d38ddc0196..15909d83ed 100644 --- a/Spigot-Server-Patches/0139-Chunk-registration-fixes.patch +++ b/Spigot-Server-Patches/0139-Chunk-registration-fixes.patch @@ -1,4 +1,4 @@ -From 4187997e2e34556a257a9eb5161104f2f5bec416 Mon Sep 17 00:00:00 2001 +From c77ae6f712e3d8402a0aafe3e543cae5b24754d9 Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-Server-Patches/0317-Always-process-chunk-removal-in-removeEntity.patch b/Spigot-Server-Patches/0317-Always-process-chunk-removal-in-removeEntity.patch new file mode 100644 index 0000000000..450a4f0927 --- /dev/null +++ b/Spigot-Server-Patches/0317-Always-process-chunk-removal-in-removeEntity.patch @@ -0,0 +1,33 @@ +From c461973839a211b635e7b8446d8acc317726398f Mon Sep 17 00:00:00 2001 +From: Aikar +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 + diff --git a/Spigot-Server-Patches/0318-Ignore-Dead-Entities-in-entityList-iteration.patch b/Spigot-Server-Patches/0318-Ignore-Dead-Entities-in-entityList-iteration.patch new file mode 100644 index 0000000000..47c686d7d0 --- /dev/null +++ b/Spigot-Server-Patches/0318-Ignore-Dead-Entities-in-entityList-iteration.patch @@ -0,0 +1,103 @@ +From e45fe59859d3c44a5175828b4c1727227265bc84 Mon Sep 17 00:00:00 2001 +From: Aikar +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 entities = world.entityList; + entities.forEach(e -> { + MinecraftKey key = e.getMinecraftKey(); ++ if (e.shouldBeRemoved) return; // Paper + + MutablePair> 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 + diff --git a/Spigot-Server-Patches/0319-Always-process-chunk-registration-after-moving.patch b/Spigot-Server-Patches/0319-Always-process-chunk-registration-after-moving.patch new file mode 100644 index 0000000000..9777158002 --- /dev/null +++ b/Spigot-Server-Patches/0319-Always-process-chunk-registration-after-moving.patch @@ -0,0 +1,55 @@ +From 82f4d6d15006e4980cee1d2645bf24c35c0c23d2 Mon Sep 17 00:00:00 2001 +From: Aikar +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 +