Paper/patches/server/0227-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch
Spottedleaf 730882fca9 Chunk System and Starlight WIP
Chunk system patch was refactored to take advantage of
newer ConcurrentUtil's concurrent long hash table (which
fixes hash collisions caused by chaining fastutil's long hash
and CHM's hash) plus some other minor improvements.

The chunk system was also merged with Starlight, which mostly
provides a small improvement to ThreadedLevelLightEngine#checkBlock
as the scheduling was rewritten.
2024-06-14 17:39:15 -07:00

76 lines
4.5 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
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index d04b69838c6f5fd1808782cacb31c6e00087bbac..96b7f0ac35a1e87c3f78a24180b207c32749fb71 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1321,6 +1321,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
playerchunkmap_entitytracker.updatePlayers(this.level.players());
if (entity instanceof ServerPlayer) {
@@ -1361,7 +1362,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
if (playerchunkmap_entitytracker1 != null) {
playerchunkmap_entitytracker1.broadcastRemoved();
}
-
+ entity.tracker = null; // Paper - We're no longer tracked
}
protected void tick() {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index ce6be7aed7b392c3e0c851f3f6e1e216bccceaf5..b151506b96a51c74ba408cb555a4d38507b2f8c1 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1201,6 +1201,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
// CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
+ // Paper start - extra debug info
+ if (entity.valid) {
+ MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable());
+ return true;
+ }
+ // Paper end - extra debug info
if (entity.isRemoved()) {
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
return false;
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 4ba77d4b109bc33d47130519c1fac704434d393d..3830440b913bd2693f2922483e57419c76117315 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -250,6 +250,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
private CraftEntity bukkitEntity;
+ public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper
public CraftEntity getBukkitEntity() {
if (this.bukkitEntity == null) {
this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this);
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
index 38df704dca30ef08f4d0831dc1cc48c6d6f71a4d..ed6aea7a38ef6e80c300ff9b012dcdbc390ad2c7 100644
--- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
@@ -33,6 +33,14 @@ public class EntityLookup<T extends EntityAccess> {
UUID uUID = entity.getUUID();
if (this.byUuid.containsKey(uUID)) {
LOGGER.warn("Duplicate entity UUID {}: {}", uUID, entity);
+ // Paper start - extra debug info
+ if (entity instanceof net.minecraft.world.entity.Entity) {
+ final T old = this.byUuid.get(entity.getUUID());
+ if (old instanceof net.minecraft.world.entity.Entity oldCast && oldCast.getId() != entity.getId() && oldCast.valid) {
+ LOGGER.error("Overwrote an existing entity {} with {}", oldCast, entity);
+ }
+ }
+ // Paper end - extra debug info
} else {
this.byUuid.put(uUID, entity);
this.byId.put(entity.getId(), entity);