Merge branch 'master' into pre/1.13
* master: make dupe uuid saferegen delete range configurable Entity add to world fixes - #1223
This commit is contained in:
commit
9078464e74
4 changed files with 101 additions and 38 deletions
|
@ -1,4 +1,4 @@
|
|||
From d54ed04c17db7c5aab315cb20b533fcb5e219a36 Mon Sep 17 00:00:00 2001
|
||||
From b33ba2c65078dfc4d47efb00482d1ac0907d282a Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 21 Jul 2018 14:27:34 -0400
|
||||
Subject: [PATCH] Duplicate UUID Resolve Option
|
||||
|
@ -33,10 +33,10 @@ 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.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 7bd7aa0d94..809441fc63 100644
|
||||
index 7bd7aa0d94..37315233e1 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -430,4 +430,45 @@ public class PaperWorldConfig {
|
||||
@@ -430,4 +430,47 @@ public class PaperWorldConfig {
|
||||
log("Bed Search Radius: " + bedSearchRadius);
|
||||
}
|
||||
}
|
||||
|
@ -45,13 +45,15 @@ index 7bd7aa0d94..809441fc63 100644
|
|||
+ SAFE_REGEN, REGEN, DELETE, NOTHING, WARN
|
||||
+ }
|
||||
+ public DuplicateUUIDMode duplicateUUIDMode = DuplicateUUIDMode.SAFE_REGEN;
|
||||
+ public int duplicateUUIDDeleteRange = 32;
|
||||
+ private void repairDuplicateUUID() {
|
||||
+ String desiredMode = getString("duplicate-uuid-resolver", "saferegen").toLowerCase().trim();
|
||||
+ duplicateUUIDDeleteRange = getInt("duplicate-uuid-saferegen-delete-range", duplicateUUIDDeleteRange);
|
||||
+ switch (desiredMode.toLowerCase()) {
|
||||
+ case "saferegen":
|
||||
+ case "saferegenerate":
|
||||
+ duplicateUUIDMode = DuplicateUUIDMode.SAFE_REGEN;
|
||||
+ log("Duplicate UUID Resolve: Safer Regenerate New UUID (Delete likely duplicates)");
|
||||
+ log("Duplicate UUID Resolve: Safer Regenerate New UUID (Delete likely duplicates within " + duplicateUUIDDeleteRange + " blocks)");
|
||||
+ break;
|
||||
+ case "regen":
|
||||
+ case "regenerate":
|
||||
|
@ -83,7 +85,7 @@ index 7bd7aa0d94..809441fc63 100644
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index 1997cbdc65..a593a798c9 100644
|
||||
index 1997cbdc65..724c1f5720 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -1,5 +1,10 @@
|
||||
|
@ -123,7 +125,7 @@ index 1997cbdc65..a593a798c9 100644
|
|||
+ Map<UUID, Entity> thisChunk = new HashMap<>();
|
||||
+ for (Iterator<Entity> iterator = ((List<Entity>) entityslice).iterator(); iterator.hasNext(); ) {
|
||||
+ Entity entity = iterator.next();
|
||||
+ if (entity.dead) continue;
|
||||
+ if (entity.dead || entity.valid) continue;
|
||||
+ Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID);
|
||||
+ if (other == null || other.dead || world.getEntityUnloadQueue().contains(other)) {
|
||||
+ other = thisChunk.get(entity.uniqueID);
|
||||
|
@ -132,7 +134,7 @@ index 1997cbdc65..a593a798c9 100644
|
|||
+ if (mode == DuplicateUUIDMode.SAFE_REGEN && other != null && !other.dead &&
|
||||
+ !world.getEntityUnloadQueue().contains(other)
|
||||
+ && java.util.Objects.equals(other.getSaveID(), entity.getSaveID())
|
||||
+ && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < 24
|
||||
+ && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < world.paperConfig.duplicateUUIDDeleteRange
|
||||
+ ) {
|
||||
+ logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + " because it was near the duplicate and likely an actual duplicate. See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about.");
|
||||
+ entity.die();
|
||||
|
@ -177,7 +179,7 @@ index ff22feee4d..9ab6350587 100644
|
|||
this.uniqueID = uuid;
|
||||
this.au = this.uniqueID.toString();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 29678af2de..0de1847639 100644
|
||||
index a8b317cee3..d5ec209feb 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -72,7 +72,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 58d0f47f63481d1f00a5aa9628248cb1e77e58ef Mon Sep 17 00:00:00 2001
|
||||
From 8fa25b04317e850b5612233ece8241b6c7cc7938 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 21 Apr 2018 11:21:48 -0400
|
||||
Subject: [PATCH] Configurable Allowance of Permanent Chunk Loaders
|
||||
|
@ -7,10 +7,10 @@ This disables the behavior that allows players to keep chunks permanently loaded
|
|||
by default and allows server operators to enable it if they wish.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 809441fc63..4a135d84db 100644
|
||||
index 37315233e1..044da2754d 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -471,4 +471,9 @@ public class PaperWorldConfig {
|
||||
@@ -473,4 +473,9 @@ public class PaperWorldConfig {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 1c7a3f36379778527ce9725cbeb9f5cab5e1475f Mon Sep 17 00:00:00 2001
|
||||
From 7802ea3ea3915637d1e5bd381e15eefbb08a487c Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 26 Jul 2018 00:11:12 -0400
|
||||
Subject: [PATCH] Prevent Saving Bad entities to chunks
|
||||
|
@ -56,32 +56,6 @@ index a97e024ec4..bd52bf6561 100644
|
|||
|
||||
nbttagcompound.set("Entities", nbttaglist1);
|
||||
NBTTagList nbttaglist2 = new NBTTagList();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 3c9d9f1ab0..0f2dadfa39 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1066,7 +1066,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
||||
}
|
||||
|
||||
this.getChunkAt(i, j).a(entity);
|
||||
- this.entityList.add(entity);
|
||||
+ if (!entity.dead) this.entityList.add(entity); // Paper - don't add dead entities, chunk registration may of killed it
|
||||
this.b(entity);
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 7a9f28421b..b57e1ff364 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -992,7 +992,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
if (this.entitiesByUUID.containsKey(uuid)) {
|
||||
Entity entity1 = (Entity) this.entitiesByUUID.get(uuid);
|
||||
|
||||
- if (this.g.contains(entity1)) {
|
||||
+ if (this.g.contains(entity1) || entity1.dead) { // Paper - overwrite the current dead one
|
||||
this.g.remove(entity1);
|
||||
} else {
|
||||
if (!(entity instanceof EntityHuman)) {
|
||||
--
|
||||
2.18.0
|
||||
|
||||
|
|
87
Spigot-Server-Patches/0330-Entity-add-to-world-fixes.patch
Normal file
87
Spigot-Server-Patches/0330-Entity-add-to-world-fixes.patch
Normal file
|
@ -0,0 +1,87 @@
|
|||
From 3e9b3f4d8b6149ca9886f827178201af8944e4df Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 3 Aug 2018 22:47:46 -0400
|
||||
Subject: [PATCH] Entity add to world fixes
|
||||
|
||||
1) Chunk Registration might kill an entity, don't add it to the world if it did!
|
||||
|
||||
2) By default, entities are added to the world per slice iteration.
|
||||
This opens risk of the slices being manipulated during chunk add if an
|
||||
EntityAddToWorldEvent spawns an entity into this chunk.
|
||||
Fix this by differing entity add to world for all entities at the same time
|
||||
|
||||
3) If a duplicate entity is attempted to add to the world of an entity, and
|
||||
the original entity is dead, overwrite it as the logic does for unloaod queued entities.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index e510940ab3..db8fbc006d 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -902,6 +902,7 @@ public class Chunk implements IChunkAccess {
|
||||
this.world.b(this.tileEntities.values());
|
||||
List[] aentityslice = this.entitySlices; // Spigot
|
||||
int i = aentityslice.length;
|
||||
+ List<Entity> toAdd = new java.util.ArrayList<>(32); // Paper
|
||||
|
||||
for (int j = 0; j < i; ++j) {
|
||||
List entityslice = aentityslice[j]; // Spigot
|
||||
@@ -948,10 +949,12 @@ public class Chunk implements IChunkAccess {
|
||||
thisChunk.put(entity.uniqueID, entity);
|
||||
}
|
||||
}
|
||||
- // Paper end
|
||||
|
||||
- this.world.a((Collection) entityslice);
|
||||
+ //this.world.a((Collection) entityslice); // Move down, add all entities at same time
|
||||
+ toAdd.addAll(entityslice);
|
||||
+ // Paper end
|
||||
}
|
||||
+ this.world.addChunkEntities(toAdd); // Paper - add all at same time to avoid entities adding to world modifying slice state
|
||||
|
||||
// CraftBukkit start
|
||||
org.bukkit.Server server = this.world.getServer();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index a0de56c938..c4a1792911 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -1069,6 +1069,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
||||
}
|
||||
|
||||
this.getChunkAt(i, j).a(entity);
|
||||
+ if (entity.dead) return false; // Paper - don't add dead entities, chunk registration may of killed it
|
||||
this.entityList.add(entity);
|
||||
this.b(entity);
|
||||
return true;
|
||||
@@ -2463,6 +2464,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
||||
return i;
|
||||
}
|
||||
|
||||
+ public void addChunkEntities(Collection<Entity> collection) { a(collection); } // Paper - OBFHELPER
|
||||
public void a(Collection<Entity> collection) {
|
||||
org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
|
||||
// CraftBukkit start
|
||||
@@ -2472,7 +2474,7 @@ public abstract class World implements GeneratorAccess, IIBlockAccess, AutoClose
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = (Entity) iterator.next();
|
||||
|
||||
- if (entity == null) {
|
||||
+ if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities
|
||||
continue;
|
||||
}
|
||||
this.entityList.add(entity);
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 7a9f28421b..6412715b78 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -992,7 +992,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
||||
if (this.entitiesByUUID.containsKey(uuid)) {
|
||||
Entity entity1 = (Entity) this.entitiesByUUID.get(uuid);
|
||||
|
||||
- if (this.g.contains(entity1)) {
|
||||
+ if (this.g.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite
|
||||
this.g.remove(entity1);
|
||||
} else {
|
||||
if (!(entity instanceof EntityHuman)) {
|
||||
--
|
||||
2.18.0
|
||||
|
Loading…
Reference in a new issue