Fix Dupe UUID logic triggering when the duplicate is pending unload

Vanilla logic checks unload queue and overwrites if its in it.
we're triggering this if a chunk unloads, and reloads immediately in same tick.

Added check for unload queue to not treat as duplicate

Also fixed the config setting not even loading
This commit is contained in:
Aikar 2018-07-28 01:20:06 -04:00
parent 3c8a4cb1bb
commit 6cd0bd29ab
2 changed files with 24 additions and 25 deletions

View file

@ -33,7 +33,7 @@ But for those who are ok with leaving this inconsistent behavior, you may use WA
It is recommended you regenerate the entities, as these were legit entities, and deserve your love. It is recommended you regenerate the entities, as these were legit entities, and deserve your love.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 14c8edeffc..e3f6557e1f 100644 index 14c8edeffc..1f4e438c1f 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
@ -45,7 +45,7 @@ index 14c8edeffc..e3f6557e1f 100644
+ REGEN, DELETE, NOTHING, WARN + REGEN, DELETE, NOTHING, WARN
+ } + }
+ public DuplicateUUIDMode duplicateUUIDMode = DuplicateUUIDMode.REGEN; + public DuplicateUUIDMode duplicateUUIDMode = DuplicateUUIDMode.REGEN;
+ public void repairDuplicateUUID() { + private void repairDuplicateUUID() {
+ String desiredMode = getString("duplicate-uuid-resolver", "regenerate").toLowerCase().trim(); + String desiredMode = getString("duplicate-uuid-resolver", "regenerate").toLowerCase().trim();
+ switch (desiredMode.toLowerCase()) { + switch (desiredMode.toLowerCase()) {
+ case "regen": + case "regen":
@ -78,7 +78,7 @@ index 14c8edeffc..e3f6557e1f 100644
+ } + }
} }
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index f1815d3766..7a62fae332 100644 index f1815d3766..74612a3924 100644
--- a/src/main/java/net/minecraft/server/Chunk.java --- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
@ -114,15 +114,16 @@ index f1815d3766..7a62fae332 100644
List entityslice = aentityslice[j]; // Spigot List entityslice = aentityslice[j]; // Spigot
+ // Paper start + // Paper start
+ DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode; + DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode;
+ if (mode == DuplicateUUIDMode.DELETE || mode == DuplicateUUIDMode.REGEN) { + if (mode == DuplicateUUIDMode.WARN | mode == DuplicateUUIDMode.DELETE || mode == DuplicateUUIDMode.REGEN) {
+ Map<UUID, Entity> thisChunk = new HashMap<>(); + Map<UUID, Entity> thisChunk = new HashMap<>();
+ for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) { + for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) {
+ Entity entity = iterator.next(); + Entity entity = iterator.next();
+ if (entity.dead) continue;
+ Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID); + Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID);
+ if (other == null) { + if (other == null || other.dead || world.getEntityUnloadQueue().contains(other)) {
+ other = thisChunk.get(entity.uniqueID); + other = thisChunk.get(entity.uniqueID);
+ } + }
+ if (other != null) { + if (other != null && !other.dead) {
+ switch (mode) { + switch (mode) {
+ case REGEN: { + case REGEN: {
+ entity.setUUID(UUID.randomUUID()); + entity.setUUID(UUID.randomUUID());
@ -135,6 +136,9 @@ index f1815d3766..7a62fae332 100644
+ iterator.remove(); + iterator.remove();
+ break; + break;
+ } + }
+ default:
+ logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", doing nothing to " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
+ break;
+ } + }
+ } + }
+ thisChunk.put(entity.uniqueID, entity); + thisChunk.put(entity.uniqueID, entity);
@ -156,6 +160,19 @@ index 93ab050fa6..fdabb1e369 100644
public void a(UUID uuid) { public void a(UUID uuid) {
this.uniqueID = uuid; this.uniqueID = uuid;
this.ar = this.uniqueID.toString(); this.ar = this.uniqueID.toString();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 52adee8806..b4de3b515a 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
}
};
// Spigot end
- protected final Set<Entity> f = Sets.newHashSet(); // Paper
+ protected final Set<Entity> f = Sets.newHashSet(); public Set<Entity> getEntityUnloadQueue() { return f; };// Paper - OBFHELPER
//public final List<TileEntity> tileEntityList = Lists.newArrayList(); // Paper - remove unused list
public final List<TileEntity> tileEntityListTick = Lists.newArrayList();
private final List<TileEntity> b = Lists.newArrayList();
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 994d4bbb84..1244baf45a 100644 index 994d4bbb84..1244baf45a 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java --- a/src/main/java/net/minecraft/server/WorldServer.java

View file

@ -17,24 +17,6 @@ an invalid entity.
This should reduce log occurrences of dupe uuid messages. This should reduce log occurrences of dupe uuid messages.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index be0b411e5c..e5a5217429 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -0,0 +0,0 @@ public class Chunk {
Map<UUID, Entity> thisChunk = new HashMap<>();
for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) {
Entity entity = iterator.next();
+ if (entity.dead) continue;
Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID);
if (other == null) {
other = thisChunk.get(entity.uniqueID);
}
- if (other != null) {
+ if (other != null && !other.dead) {
switch (mode) {
case REGEN: {
entity.setUUID(UUID.randomUUID());
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index bcce5e8b7e..bad287fca4 100644 index bcce5e8b7e..bad287fca4 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@ -75,7 +57,7 @@ index bcce5e8b7e..bad287fca4 100644
nbttagcompound.set("Entities", nbttaglist1); nbttagcompound.set("Entities", nbttaglist1);
NBTTagList nbttaglist2 = new NBTTagList(); NBTTagList nbttaglist2 = new NBTTagList();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 52adee8806..c2b92ad3a5 100644 index b4de3b515a..d2d2ab794b 100644
--- a/src/main/java/net/minecraft/server/World.java --- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { @@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {