Paper/Spigot-Server-Patches/0250-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
Aikar e4d10a6d67
Updated Upstream (Bukkit/CraftBukkit)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
122289ff Add FaceAttachable interface to handle Grindstone facing in common with Switches
a6db750e SPIGOT-5647: ZombieVillager entity should have getVillagerType()

CraftBukkit Changes:
bbe3d58e SPIGOT-5650: Lectern.setPage(int) causes a NullPointerException
3075579f Add FaceAttachable interface to handle Grindstone facing in common with Switches
95bd4238 SPIGOT-5647: ZombieVillager entity should have getVillagerType()
4d975ac3 SPIGOT-5617: setBlockData does not work when NotPlayEvent is called by redstone current
2020-04-02 17:09:17 -04:00

127 lines
6.5 KiB
Diff

From 9a76930aea280a0e6eab6f01334f409f4fccd808 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 21 Jul 2018 08:25:40 -0400
Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
Add -Ddebug.entities=true to your JVM flags to gain more information
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index dce1e2af62..d39037a979 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -76,6 +76,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
private CraftEntity bukkitEntity;
+ PlayerChunkMap.EntityTracker tracker; // Paper
+ Throwable addedToWorldStack; // Paper - entity debug
public CraftEntity getBukkitEntity() {
if (bukkitEntity == null) {
bukkitEntity = CraftEntity.getEntity(world.getServer(), this);
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index fcf229ad5d..f640d2ac76 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1061,6 +1061,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
} else {
PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = new PlayerChunkMap.EntityTracker(entity, i, j, entitytypes.isDeltaTracking());
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
playerchunkmap_entitytracker.track(this.world.getPlayers());
if (entity instanceof EntityPlayer) {
@@ -1103,7 +1104,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
if (playerchunkmap_entitytracker1 != null) {
playerchunkmap_entitytracker1.a();
}
-
+ entity.tracker = null; // Paper - We're no longer tracked
}
protected void g() {
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index f349c7fe2e..cab9ec5dd4 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -63,6 +63,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
public boolean pvpMode;
public boolean keepSpawnInMemory = true;
public org.bukkit.generator.ChunkGenerator generator;
+ public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
public boolean captureBlockStates = false;
public boolean captureTreeGeneration = false;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 4cbf390ce0..6ce7f77a5e 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -76,6 +76,9 @@ public class WorldServer extends World {
// CraftBukkit start
private int tickPosition;
boolean hasPhysicsEvent = true; // Paper
+ private static Throwable getAddToWorldStackTrace(Entity entity) {
+ return new Throwable(entity + " Added to world at " + new java.util.Date());
+ }
// Add env and gen to constructor
public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
@@ -998,8 +1001,28 @@ public class WorldServer extends World {
// CraftBukkit start
private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
- if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); return true; } // Paper
+ // Paper start
+ if (entity.valid) {
+ MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
+
+ if (DEBUG_ENTITIES) {
+ Throwable thr = entity.addedToWorldStack;
+ if (thr == null) {
+ MinecraftServer.LOGGER.error("Double add entity has no add stacktrace");
+ } else {
+ MinecraftServer.LOGGER.error("Double add stacktrace: ", thr);
+ }
+ }
+ return true;
+ }
+ // Paper end
if (entity.dead) {
+ // Paper start
+ if (DEBUG_ENTITIES) {
+ new Throwable("Tried to add entity " + entity + " but it was marked as removed already").printStackTrace(); // CraftBukkit
+ getAddToWorldStackTrace(entity).printStackTrace();
+ }
+ // Paper end
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit
return false;
} else if (this.isUUIDTaken(entity)) {
@@ -1172,7 +1195,24 @@ public class WorldServer extends World {
}
}
- this.entitiesByUUID.put(entity.getUniqueID(), entity);
+ if (DEBUG_ENTITIES) {
+ entity.addedToWorldStack = getAddToWorldStackTrace(entity);
+ }
+
+ Entity old = this.entitiesByUUID.put(entity.getUniqueID(), entity);
+ if (old != null && old.getId() != entity.getId() && old.valid) {
+ Logger logger = LogManager.getLogger();
+ logger.error("Overwrote an existing entity " + old + " with " + entity);
+ if (DEBUG_ENTITIES) {
+ if (old.addedToWorldStack != null) {
+ old.addedToWorldStack.printStackTrace();
+ } else {
+ logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
+ }
+ entity.addedToWorldStack.printStackTrace();
+ }
+ }
+
this.getChunkProvider().addEntity(entity);
// CraftBukkit start - SPIGOT-5278
if (entity instanceof EntityDrowned) {
--
2.25.1