c97ce029e9
PaperMC believes that 1.16.2 is now ready for general release as we fixed the main issue plagueing the 1.16.x release, the MapLike data conversion issues. Until now, it was not safe for a server to convert a world to 1.16.2 without data conversion issues around villages and potentially other things. If you did, those MapLike errors meant something went wrong. This is now resolved. Big thanks to all those that helped, notably @BillyGalbreath and @Proximyst who did large parts of the update process with me. Please as always, backup your worlds and test before updating to 1.16.2! If you update to 1.16.2, there is no going back to an older build than this. --------------------------------- Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com> Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com> Co-authored-by: krolik-exe <69214078+krolik-exe@users.noreply.github.com> Co-authored-by: BillyGalbreath <BillyGalbreath@users.noreply.github.com> Co-authored-by: stonar96 <minecraft.stonar96@gmail.com> Co-authored-by: Shane Freeder <theboyetronic@gmail.com> Co-authored-by: Jason <jasonpenilla2@me.com> Co-authored-by: kashike <kashike@vq.lc> Co-authored-by: Aurora <21148213+aurorasmiles@users.noreply.github.com> Co-authored-by: KennyTV <kennytv@t-online.de> Co-authored-by: commandblockguy <commandblockguy1@gmail.com> Co-authored-by: DigitalRegent <misterwener@gmail.com> Co-authored-by: ishland <ishlandmc@yeah.net>
123 lines
6.6 KiB
Diff
123 lines
6.6 KiB
Diff
From 0000000000000000000000000000000000000000 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 d62d25af15dee1457df85dbc4db6f7f0a632ecba..b1d7c30690e09f60075b9d2cff47d6a53115118b 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -78,6 +78,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 8862bbd73b627e37709d46e6aeeee70c89cbd821..4bbcd00950405a4bf3ce391b557049a3b1d4aee8 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -1093,6 +1093,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) {
|
|
@@ -1134,7 +1135,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 275442e07743e4e4e3f1468f58c50bb38ab7537a..b6af67e7625dd6e24fad5812d4b563b6ce91bede 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -68,6 +68,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 5e6a39ded0405d8ab8ba26d2a9f152cda0fa94fb..bd0e35fac15ca559d6508df8c7f593af036ab551 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -84,6 +84,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
public final Convertable.ConversionSession convertable;
|
|
public final UUID uuid;
|
|
boolean hasPhysicsEvent = true; // Paper
|
|
+ private static Throwable getAddToWorldStackTrace(Entity entity) {
|
|
+ return new Throwable(entity + " Added to world at " + new java.util.Date());
|
|
+ }
|
|
|
|
@Override public Chunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
|
return this.chunkProvider.getChunkAt(x, z, false);
|
|
@@ -919,8 +922,28 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
// 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)) {
|
|
@@ -1117,7 +1140,24 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
}
|
|
}
|
|
|
|
- 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) {
|