papermc/Spigot-Server-Patches/0336-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
Aikar 42f6bebcc3
Prevent Saving Bad entities to chunks
See https://github.com/PaperMC/Paper/issues/1223

Should fix Vanilla bugs

Minecraft is saving invalid entities to the chunk files.

Avoid saving bad data, and also make improvements to handle
loading these chunks. Any invalid entity will be instant killed,
so lets avoid adding it to the world...

This lets us be safer about the dupe UUID resolver too, as now
we can ignore instant killed entities and avoid risk of duplicating
an invalid entity.

This should reduce log occurrences of dupe uuid messages.

Also reduce the logging spam overall.
2018-07-26 00:51:20 -04:00

95 lines
4.5 KiB
Diff

From fd5af731abdbb7f69e1faa16cd763c44018f643c 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 99dac412f0..0d3af8cb77 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 ICommandListener, KeyedObject { // Paper
}
return bukkitEntity;
}
+ Throwable addedToWorldStack; // Paper - entity debug
// CraftBukikt end
private static final Logger a = LogManager.getLogger();
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index b16324e1a2..994d4bbb84 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -7,6 +7,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -53,6 +54,10 @@ public class WorldServer extends World implements IAsyncTaskHandler {
private final List<NextTickListEntry> W = Lists.newArrayList();
// CraftBukkit start
+ 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 Date());
+ }
public final int dimension;
// Add env and gen to constructor
@@ -1160,6 +1165,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", EntityTypes.a(entity)); // CraftBukkit // Paper
+ if (DEBUG_ENTITIES) getAddToWorldStackTrace(entity).printStackTrace();
return false;
} else {
UUID uuid = entity.getUniqueID();
@@ -1171,8 +1177,14 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.f.remove(entity1);
} else {
if (!(entity instanceof EntityHuman)) {
- WorldServer.a.error("Keeping entity {} that already exists with UUID {} - " + entity1, EntityTypes.a(entity1), 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;
}
@@ -1189,7 +1201,24 @@ 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.bb();
if (aentity != null) {
--
2.18.0