From 3e0934988343ec1ba1f5950d8302636c306ebc0d Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 23 Jul 2018 22:44:23 -0400 Subject: [PATCH] Monitor and detect illegal Entity slice state If we detect unexpected state, try to recover This should hopefully avoid duplicate entities ever being created if the entity was to end up in 2 different chunk slices diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index e5c900a85..e4d5e65c8 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -681,8 +681,27 @@ public class Chunk { entity.ab = this.locX; entity.ac = k; entity.ad = this.locZ; - this.entitySlices[k].add(entity); + // Paper start + List entitySlice = this.entitySlices[k]; + boolean inThis = entitySlice.contains(entity); + List currentSlice = entity.entitySlice; + if (inThis || (currentSlice != null && currentSlice.contains(entity))) { + if (currentSlice == entitySlice || inThis) { + return; + } else { + Chunk chunk = entity.getCurrentChunk(); + if (chunk != null) { + chunk.removeEntity(entity); + } else { + removeEntity(entity); + } + currentSlice.remove(entity); // Just incase the above did not remove from this target slice + } + } + entity.entitySlice = entitySlice; + entitySlice.add(entity); + this.markDirty(); entity.setCurrentChunk(this); entityCounts.increment(entity.getMinecraftKeyString()); @@ -725,6 +744,9 @@ public class Chunk { } // Paper start + if (entity.entitySlice == null || !entity.entitySlice.contains(entity) || entitySlices[i] == entity.entitySlice) { + entity.entitySlice = null; + } if (!this.entitySlices[i].remove(entity)) { return; } this.markDirty(); entity.setCurrentChunk(null); @@ -955,6 +977,7 @@ public class Chunk { } // Spigot End entity.setCurrentChunk(null); // Paper + entity.entitySlice = null; // Paper // Do not pass along players, as doing so can get them stuck outside of time. // (which for example disables inventory icon updates and prevents block breaking) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index b761524f0..a2654690f 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -59,6 +59,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } } }; + List entitySlice = null; // Paper end static boolean isLevelAtLeast(NBTTagCompound tag, int level) { return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; -- 2.21.0