Paper/Spigot-Server-Patches/0267-Add-some-Debug-to-Chunk-Entity-slices.patch
2019-05-13 21:20:58 -05:00

74 Zeilen
3.2 KiB
Diff

From bcc772b0a83f8c5a792ff5439b4220238a7665e1 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 23 Jul 2018 22:44:23 -0400
Subject: [PATCH] Add some Debug to Chunk Entity slices
If we detect unexpected state, log and 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 8a8c8f4e8..fd91cf839 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -403,6 +403,25 @@ public class Chunk implements IChunkAccess {
if (k >= this.entitySlices.length) {
k = this.entitySlices.length - 1;
}
+ // Paper - remove from any old list if its in one
+ List<Entity> nextSlice = this.entitySlices[k]; // the next list to be added to
+ List<Entity> currentSlice = entity.entitySlice;
+ if (nextSlice == currentSlice) {
+ if (World.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity was already in this chunk!" + entity, new Throwable());
+ return; // ??? silly plugins
+ }
+ if (currentSlice != null && currentSlice.contains(entity)) {
+ // Still in an old chunk...
+ if (World.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity is still in another chunk!" + entity, new Throwable());
+ Chunk chunk = entity.getCurrentChunk();
+ if (chunk != null) {
+ chunk.removeEntity(entity);
+ } else {
+ removeEntity(entity);
+ }
+ currentSlice.remove(entity); // Just incase the above did not remove from the previous slice
+ }
+ // Paper end
if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper
entity.inChunk = true;
@@ -411,6 +430,7 @@ public class Chunk implements IChunkAccess {
entity.chunkY = k;
entity.chunkZ = this.loc.z;
this.entitySlices[k].add(entity);
+ entity.entitySlice = this.entitySlices[k]; // Paper
this.markDirty(); // Paper
}
@@ -434,6 +454,9 @@ public class Chunk implements IChunkAccess {
}
// Paper start
if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
+ if (entitySlices[i] == entity.entitySlice) {
+ entity.entitySlice = null;
+ }
if (!this.entitySlices[i].remove(entity)) {
return;
}
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index e3b1ebe62..2484eb0ff 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -67,6 +67,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
}
};
+ List<Entity> entitySlice = null;
// Paper end
static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
--
2.21.0