PaperMC/Spigot-Server-Patches/0295-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
Aikar 2dd8623548
Updated Upstream (CraftBukkit/Spigot)
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

CraftBukkit Changes:
7033f180 Hoist out synchronisation from ChunkRegionLoader

Spigot Changes:
500ff5d4 Rebuild patches

Additional Paper changes:
Fixed Versioned World Folders to not synchronize on ChunkRegionLoader
Optimized Save Queue even more to use a Long2ObjectOpenHashmap for save map
Add World#getXIfLoaded to IWorldReader to expose it to more places
2018-09-10 23:14:02 -04:00

88 lines
4.6 KiB
Diff

From d1635cbba84d8963e9930db2a967df7e311c9be2 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 064bd4133a..7d8f723968 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -73,6 +73,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/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 6987d9423c..8e8cf659f8 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -55,6 +55,10 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// CraftBukkit start
public final DimensionManager dimension;
+ private static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // 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, IDataManager idatamanager, PersistentCollection persistentcollection, WorldData worlddata, DimensionManager dimensionmanager, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
@@ -975,6 +979,7 @@ 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: " + entity); // CraftBukkit // Paper
+ if (DEBUG_ENTITIES) getAddToWorldStackTrace(entity).printStackTrace();
return false;
} else {
UUID uuid = entity.getUniqueID();
@@ -986,8 +991,14 @@ 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("Keeping entity {} that already exists with UUID {}", entity1, uuid.toString()); // CraftBukkit // Paper
WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper
+ if (DEBUG_ENTITIES) {
+ if (entity1.addedToWorldStack != null) {
+ entity1.addedToWorldStack.printStackTrace();
+ }
+ getAddToWorldStackTrace(entity).printStackTrace();
+ }
return false;
}
@@ -1004,7 +1015,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.18.0