Paper/Spigot-Server-Patches/0289-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
Shane Freeder fb25dc17c6 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:
da08d022 SPIGOT-4700: Add PlayerFishEvent.State.REEL_IN
0cef14e4 Remove draft API from selectEntities

CraftBukkit Changes:
a46fdbc6 Remove outdated build delay.
3697519b SPIGOT-4708: Fix ExactChoice recipes neglecting material
9ead7009 SPIGOT-4677: Add minecraft.admin.command_feedback permission
c3749a23 Remove the Damage tag from items when it is 0.
f74c7b95 SPIGOT-4706: Can't interact with active item
494eef45 Mention requirement of JIRA ticket for bug fixes
51d62dec SPIGOT-4702: Exception when middle clicking certain slots
be557e69 SPIGOT-4700: Add PlayerFishEvent.State.REEL_IN
2019-04-22 22:36:14 +01:00

108 lines
5.5 KiB
Diff

From 0a837c25363d2b05d8a03aa1f80adf0502ca126c 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 69a058d830..b6c46e01d9 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -71,6 +71,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
protected CraftEntity bukkitEntity;
EntityTrackerEntry 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/World.java b/src/main/java/net/minecraft/server/World.java
index c7712d2e71..1496125ddf 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -110,6 +110,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
public boolean pvpMode;
public boolean keepSpawnInMemory = true;
public 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 85a30652c4..6d1f70b39e 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -51,6 +51,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// CraftBukkit start
public final DimensionManager dimension;
+ 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, IDataManager idatamanager, PersistentCollection persistentcollection, WorldData worlddata, DimensionManager dimensionmanager, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
@@ -951,7 +954,12 @@ public class WorldServer extends World implements IAsyncTaskHandler {
private boolean j(Entity entity) {
if (entity.dead) {
- // WorldServer.a.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.P())); // CraftBukkit
+ // 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
return false;
} else {
UUID uuid = entity.getUniqueID();
@@ -963,8 +971,15 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.g.remove(entity1);
} else {
if (!(entity instanceof EntityHuman)) {
- WorldServer.a.error("Keeping entity {} that already exists with UUID {} - " + entity1, EntityTypes.getName(entity1.P()), uuid.toString()); // CraftBukkit // Paper
- WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper
+ if (DEBUG_ENTITIES) {
+ WorldServer.a.error("Keeping entity {} that already exists with UUID {}", entity1, uuid.toString()); // CraftBukkit // Paper
+ WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper
+
+ if (entity1.addedToWorldStack != null) {
+ entity1.addedToWorldStack.printStackTrace();
+ }
+ getAddToWorldStackTrace(entity).printStackTrace();
+ }
return false;
}
@@ -981,7 +996,25 @@ public class WorldServer extends World implements IAsyncTaskHandler {
protected void b(Entity entity) {
super.b(entity);
this.entitiesById.a(entity.getId(), entity);
- this.entitiesByUUID.put(entity.getUniqueID(), entity);
+ // Paper start
+ 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();
+ }
+ }
+ // Paper end
Entity[] aentity = entity.bi();
if (aentity != null) {
--
2.21.0