From fa8406dab407f007da6c91ce0a0aa5586f430f30 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 08:09:40 -0400 Subject: [PATCH 1/7] Create a symlink on not-windows to current minecraft decompile dir This is useful for project developers switching back and forth between 1.12.2 and 1.13 so we can have our IDE automatically use the current version we are working on for included mc-dev files. --- scripts/decompile.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/decompile.sh b/scripts/decompile.sh index f2c1754fd..2018259c3 100755 --- a/scripts/decompile.sh +++ b/scripts/decompile.sh @@ -6,9 +6,9 @@ PS1="$" basedir="$(cd "$1" && pwd -P)" workdir="$basedir/work" minecraftversion=$(cat "$workdir/BuildData/info.json" | grep minecraftVersion | cut -d '"' -f 4) +windows="$([[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]] && echo "true" || echo "false")" decompiledir="$workdir/Minecraft/$minecraftversion" classdir="$decompiledir/classes" - echo "Extracting NMS classes..." if [ ! -d "$classdir" ]; then mkdir -p "$classdir" @@ -30,4 +30,13 @@ if [ ! -d "$decompiledir/net/minecraft/server" ]; then exit 1 fi fi + +# set a symlink to current +currentlink="$workdir/Minecraft/current" +if ([ ! -e "$currentlink" ] || [ -L "$currentlink" ]) && [ "$windows" == "false" ]; then + echo "Pointing $currentlink to $minecraftversion" + rm -rf "$currentlink" + ln -sfn "$minecraftversion" "$currentlink" +fi + ) From 82bcd1408abe450d02d51116ab8f4dd13c3e3e88 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 09:03:10 -0400 Subject: [PATCH 2/7] Guard the Entity.SHARED_RANDOM from seed changes I don't clearly see any, but as a protection for future changes. --- ...085-Use-a-Shared-Random-for-Entities.patch | 23 +++++++++++++++---- .../0086-Don-t-teleport-dead-entities.patch | 6 ++--- ...nilla-per-world-scoreboard-coloring-.patch | 6 ++--- ...2-Vehicle-Event-Cancellation-Changes.patch | 10 ++++---- .../0128-Entity-Tracking-Improvements.patch | 6 ++--- ...6-Optional-TNT-doesn-t-move-in-water.patch | 8 +++---- .../0142-Make-entities-look-for-hoppers.patch | 6 ++--- ...5-Don-t-let-fishinghooks-use-portals.patch | 6 ++--- ...7-Vanished-players-don-t-have-rights.patch | 6 ++--- ...llow-entities-to-ride-themselves-572.patch | 6 ++--- .../0199-Cap-Entity-Collisions.patch | 6 ++--- .../0220-Entity-fromMobSpawner.patch | 10 ++++---- ...emove-entities-on-dimension-teleport.patch | 10 ++++---- 13 files changed, 61 insertions(+), 48 deletions(-) diff --git a/Spigot-Server-Patches/0085-Use-a-Shared-Random-for-Entities.patch b/Spigot-Server-Patches/0085-Use-a-Shared-Random-for-Entities.patch index 3979ac149..36b7f3406 100644 --- a/Spigot-Server-Patches/0085-Use-a-Shared-Random-for-Entities.patch +++ b/Spigot-Server-Patches/0085-Use-a-Shared-Random-for-Entities.patch @@ -1,4 +1,4 @@ -From 95dfc2d6b2593ea2603bc30932824b855b8bb672 Mon Sep 17 00:00:00 2001 +From 077011a996a7c44bb7ec934b0e46aaf16725f121 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 22 Mar 2016 00:33:47 -0400 Subject: [PATCH] Use a Shared Random for Entities @@ -6,18 +6,31 @@ Subject: [PATCH] Use a Shared Random for Entities Reduces memory usage and provides ensures more randomness, Especially since a lot of garbage entity objects get created. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index b4ad611fc..4a08db5ba 100644 +index f547dbfd0..daf97bce3 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -46,6 +46,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -46,6 +46,20 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper // CraftBukkit start private static final int CURRENT_LEVEL = 2; -+ public static Random SHARED_RANDOM = new Random(); // Paper ++ // Paper start ++ public static Random SHARED_RANDOM = new Random() { ++ private boolean locked = false; ++ @Override ++ public synchronized void setSeed(long seed) { ++ if (locked) { ++ LogManager.getLogger().error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable()); ++ } else { ++ super.setSeed(seed); ++ locked = true; ++ } ++ } ++ }; ++ // Paper end static boolean isLevelAtLeast(NBTTagCompound tag, int level) { return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; } -@@ -171,7 +172,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -171,7 +185,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper this.length = 1.8F; this.ax = 1; this.ay = 1.0F; diff --git a/Spigot-Server-Patches/0086-Don-t-teleport-dead-entities.patch b/Spigot-Server-Patches/0086-Don-t-teleport-dead-entities.patch index 473a75506..008e88172 100644 --- a/Spigot-Server-Patches/0086-Don-t-teleport-dead-entities.patch +++ b/Spigot-Server-Patches/0086-Don-t-teleport-dead-entities.patch @@ -1,4 +1,4 @@ -From d24cf71aec74d0f22ad259e435ccbce611139fed Mon Sep 17 00:00:00 2001 +From 3faa48aebbc50348a1c69b43c8f4be1f0d8d78e8 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 22 Mar 2016 00:55:23 -0400 Subject: [PATCH] Don't teleport dead entities @@ -7,10 +7,10 @@ Had some issue with this in past, and this is the vanilla logic. Potentially an old CB change that's no longer needed. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index eb07d4233..e2202ed0c 100644 +index daf97bce3..87b82f908 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -2399,7 +2399,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2412,7 +2412,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } public Entity teleportTo(Location exit, boolean portal) { diff --git a/Spigot-Server-Patches/0109-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch b/Spigot-Server-Patches/0109-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch index 9ebe89918..0ae298129 100644 --- a/Spigot-Server-Patches/0109-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch +++ b/Spigot-Server-Patches/0109-Option-to-use-vanilla-per-world-scoreboard-coloring-.patch @@ -1,4 +1,4 @@ -From 90ca9d579f3d73834d58123205d8db9cfe179b56 Mon Sep 17 00:00:00 2001 +From 0f917b2215537ad0e4c08b4c4add7ad3bdec07c7 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 6 Apr 2016 01:04:23 -0500 Subject: [PATCH] Option to use vanilla per-world scoreboard coloring on names @@ -19,10 +19,10 @@ index abc1aabdd..6ea608ba9 100644 + } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index e2202ed0c..88faa4601 100644 +index 87b82f908..fa9319aff 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -2122,6 +2122,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2135,6 +2135,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper return this.getFlag(5); } diff --git a/Spigot-Server-Patches/0122-Vehicle-Event-Cancellation-Changes.patch b/Spigot-Server-Patches/0122-Vehicle-Event-Cancellation-Changes.patch index 6fd39b959..6a893f66e 100644 --- a/Spigot-Server-Patches/0122-Vehicle-Event-Cancellation-Changes.patch +++ b/Spigot-Server-Patches/0122-Vehicle-Event-Cancellation-Changes.patch @@ -1,14 +1,14 @@ -From eb11e43a94909435f4ce4020d2eded1eb0b8cdb1 Mon Sep 17 00:00:00 2001 +From 59d26d28500f04c9cced47dc4c99d71fc7efb7e5 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 22 Apr 2016 18:20:05 -0500 Subject: [PATCH] Vehicle Event Cancellation Changes diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 88faa4601..aece54d26 100644 +index fa9319aff..a3e9ee052 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -70,7 +70,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -83,7 +83,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper public boolean i; public final List passengers; protected int j; @@ -17,7 +17,7 @@ index 88faa4601..aece54d26 100644 public boolean attachedToPlayer; public World world; public double lastX; -@@ -2004,6 +2004,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2017,6 +2017,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)"); } else { // CraftBukkit start @@ -25,7 +25,7 @@ index 88faa4601..aece54d26 100644 CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle(); Entity orig = craft == null ? null : craft.getHandle(); if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { -@@ -2019,7 +2020,13 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2032,7 +2033,13 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } } // CraftBukkit end diff --git a/Spigot-Server-Patches/0128-Entity-Tracking-Improvements.patch b/Spigot-Server-Patches/0128-Entity-Tracking-Improvements.patch index 9430cc751..f6efb164a 100644 --- a/Spigot-Server-Patches/0128-Entity-Tracking-Improvements.patch +++ b/Spigot-Server-Patches/0128-Entity-Tracking-Improvements.patch @@ -1,4 +1,4 @@ -From 2c29fda252395dc3caf19e77deea3ef876473ace Mon Sep 17 00:00:00 2001 +From 76366b2e02fbcffccddaec97bd494277c0d92d55 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 17 Jun 2013 01:24:00 -0400 Subject: [PATCH] Entity Tracking Improvements @@ -7,10 +7,10 @@ If any part of a Vehicle/Passenger relationship is visible to a player, send all passenger/vehicles to the player in the chain. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index d1f07bbbd..945f06c93 100644 +index a3e9ee052..9b01c23e0 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -53,6 +53,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -66,6 +66,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper protected CraftEntity bukkitEntity; diff --git a/Spigot-Server-Patches/0136-Optional-TNT-doesn-t-move-in-water.patch b/Spigot-Server-Patches/0136-Optional-TNT-doesn-t-move-in-water.patch index aad33635f..9db6798df 100644 --- a/Spigot-Server-Patches/0136-Optional-TNT-doesn-t-move-in-water.patch +++ b/Spigot-Server-Patches/0136-Optional-TNT-doesn-t-move-in-water.patch @@ -1,4 +1,4 @@ -From d45df5fa649ad40f1cb1057bc29f5f23aed74c96 Mon Sep 17 00:00:00 2001 +From 036e57626907e289a1c0a842460a9bac8da4e5d3 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Sun, 22 May 2016 20:20:55 -0500 Subject: [PATCH] Optional TNT doesn't move in water @@ -32,10 +32,10 @@ index 067cb233e..06acdaaf0 100644 + } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index c105dd9b0..334441ed7 100644 +index 9b01c23e0..0a62ebf4a 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1114,6 +1114,11 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -1127,6 +1127,11 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } public boolean aq() { @@ -47,7 +47,7 @@ index c105dd9b0..334441ed7 100644 if (this.bJ() instanceof EntityBoat) { this.inWater = false; } else if (this.world.a(this.getBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D), Material.WATER, this)) { -@@ -2587,6 +2592,11 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2600,6 +2605,11 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } public boolean bo() { diff --git a/Spigot-Server-Patches/0142-Make-entities-look-for-hoppers.patch b/Spigot-Server-Patches/0142-Make-entities-look-for-hoppers.patch index 0670abef0..27b44cdbb 100644 --- a/Spigot-Server-Patches/0142-Make-entities-look-for-hoppers.patch +++ b/Spigot-Server-Patches/0142-Make-entities-look-for-hoppers.patch @@ -1,4 +1,4 @@ -From b882250f89918c9a9e256def49d0d5b92d7e8916 Mon Sep 17 00:00:00 2001 +From 85cc2d8515551c826977868bf3c68b1d78cccead Mon Sep 17 00:00:00 2001 From: Techcable Date: Sat, 18 Jun 2016 01:01:37 -0500 Subject: [PATCH] Make entities look for hoppers @@ -133,10 +133,10 @@ index 008ed206d..b3c1f550c 100644 this.b = i; this.c = j; diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index cb9ef622c..c675a6e16 100644 +index 0a62ebf4a..0950c315f 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -80,6 +80,19 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -93,6 +93,19 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper public double locX; public double locY; public double locZ; diff --git a/Spigot-Server-Patches/0175-Don-t-let-fishinghooks-use-portals.patch b/Spigot-Server-Patches/0175-Don-t-let-fishinghooks-use-portals.patch index 1a3627797..42c9d7aa3 100644 --- a/Spigot-Server-Patches/0175-Don-t-let-fishinghooks-use-portals.patch +++ b/Spigot-Server-Patches/0175-Don-t-let-fishinghooks-use-portals.patch @@ -1,14 +1,14 @@ -From 5f57f26f976b45cda5fcda4dffebc4981d748109 Mon Sep 17 00:00:00 2001 +From e04b0035798d951d1068d1625eda2fb758a34404 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 16 Dec 2016 16:03:19 -0600 Subject: [PATCH] Don't let fishinghooks use portals diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index c675a6e16..f71528b5f 100644 +index 0950c315f..d79844a98 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -144,7 +144,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -157,7 +157,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper public boolean ah; public boolean impulse; public int portalCooldown; diff --git a/Spigot-Server-Patches/0177-Vanished-players-don-t-have-rights.patch b/Spigot-Server-Patches/0177-Vanished-players-don-t-have-rights.patch index b886675d1..1e5936195 100644 --- a/Spigot-Server-Patches/0177-Vanished-players-don-t-have-rights.patch +++ b/Spigot-Server-Patches/0177-Vanished-players-don-t-have-rights.patch @@ -1,14 +1,14 @@ -From 570c45e9491173c215cae1bd4ff5ff9b9b8b1fa0 Mon Sep 17 00:00:00 2001 +From 6c9aa29b50e035dc386794e866d64ec07c4c9c19 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 16 Dec 2016 22:10:35 -0600 Subject: [PATCH] Vanished players don't have rights diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index f71528b5f..b13830e87 100644 +index d79844a98..6d1e61e23 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -68,7 +68,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -81,7 +81,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper private static double f = 1.0D; private static int entityCount; private int id; diff --git a/Spigot-Server-Patches/0195-Don-t-allow-entities-to-ride-themselves-572.patch b/Spigot-Server-Patches/0195-Don-t-allow-entities-to-ride-themselves-572.patch index 09b189e53..945f6e86f 100644 --- a/Spigot-Server-Patches/0195-Don-t-allow-entities-to-ride-themselves-572.patch +++ b/Spigot-Server-Patches/0195-Don-t-allow-entities-to-ride-themselves-572.patch @@ -1,14 +1,14 @@ -From 977e13e598af25e22f19ad88220a047723a12193 Mon Sep 17 00:00:00 2001 +From 512e2cf16911c2f07c0c5b763d4b56b1788344fb Mon Sep 17 00:00:00 2001 From: Alfie Cleveland Date: Sun, 8 Jan 2017 04:31:36 +0000 Subject: [PATCH] Don't allow entities to ride themselves - #572 diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index b6711dcfa..e7f63c927 100644 +index 6d1e61e23..92b2bcb86 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -1981,6 +1981,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -1994,6 +1994,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } protected void o(Entity entity) { diff --git a/Spigot-Server-Patches/0199-Cap-Entity-Collisions.patch b/Spigot-Server-Patches/0199-Cap-Entity-Collisions.patch index 7e698f005..f17af28b9 100644 --- a/Spigot-Server-Patches/0199-Cap-Entity-Collisions.patch +++ b/Spigot-Server-Patches/0199-Cap-Entity-Collisions.patch @@ -1,4 +1,4 @@ -From a30098615015d5b407960dfe74033d7545d7eb12 Mon Sep 17 00:00:00 2001 +From 1ffe7e986e130686ef5b48ac41b63296f77b4e9c Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 22 Jan 2017 18:07:56 -0500 Subject: [PATCH] Cap Entity Collisions @@ -27,10 +27,10 @@ index 5f06d4e5e..29b4bdb47 100644 + } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 20324deeb..b4233df5f 100644 +index 92b2bcb86..5a4de30fe 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -170,6 +170,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -183,6 +183,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper public final boolean defaultActivationState; public long activatedTick = Integer.MIN_VALUE; public boolean fromMobSpawner; diff --git a/Spigot-Server-Patches/0220-Entity-fromMobSpawner.patch b/Spigot-Server-Patches/0220-Entity-fromMobSpawner.patch index 571795b26..55e5e3787 100644 --- a/Spigot-Server-Patches/0220-Entity-fromMobSpawner.patch +++ b/Spigot-Server-Patches/0220-Entity-fromMobSpawner.patch @@ -1,14 +1,14 @@ -From 57ed55129a54deecee7292fd00036b45ac0bd6ed Mon Sep 17 00:00:00 2001 +From 69193e9240f2c55715208ca6341f085a2b1cabca Mon Sep 17 00:00:00 2001 From: BillyGalbreath Date: Sun, 18 Jun 2017 18:17:05 -0500 Subject: [PATCH] Entity#fromMobSpawner() diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index b4233df5f..00791faf2 100644 +index 5a4de30fe..2dbb88f2d 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -170,6 +170,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -183,6 +183,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper public final boolean defaultActivationState; public long activatedTick = Integer.MIN_VALUE; public boolean fromMobSpawner; @@ -16,7 +16,7 @@ index b4233df5f..00791faf2 100644 protected int numCollisions = 0; // Paper public void inactiveTick() { } // Spigot end -@@ -1590,6 +1591,10 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -1603,6 +1604,10 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper if (origin != null) { nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ())); } @@ -27,7 +27,7 @@ index b4233df5f..00791faf2 100644 // Paper end return nbttagcompound; } catch (Throwable throwable) { -@@ -1739,6 +1744,8 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -1752,6 +1757,8 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper if (!originTag.isEmpty()) { origin = new Location(world.getWorld(), originTag.getDoubleAt(0), originTag.getDoubleAt(1), originTag.getDoubleAt(2)); } diff --git a/Spigot-Server-Patches/0307-Properly-remove-entities-on-dimension-teleport.patch b/Spigot-Server-Patches/0307-Properly-remove-entities-on-dimension-teleport.patch index 30f2a43a6..d2c3dd0b7 100644 --- a/Spigot-Server-Patches/0307-Properly-remove-entities-on-dimension-teleport.patch +++ b/Spigot-Server-Patches/0307-Properly-remove-entities-on-dimension-teleport.patch @@ -1,4 +1,4 @@ -From b770be1d1eb24d049cd7ca1af1a96bb87aed62e3 Mon Sep 17 00:00:00 2001 +From 11c4b454e2dca08dc7d8823bf7d533e20d67c7ef Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 10 Jun 2018 20:04:42 -0400 Subject: [PATCH] Properly remove entities on dimension teleport @@ -22,10 +22,10 @@ requirement, but plugins (such as my own) use this method to trigger a "reload" of the entity on the client. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 7b17c32bb..d03e7c24f 100644 +index 2dbb88f2d..80ecdb282 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -2449,7 +2449,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2462,7 +2462,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } // CraftBukkit end */ @@ -35,14 +35,14 @@ index 7b17c32bb..d03e7c24f 100644 this.world.methodProfiler.a("reposition"); /* CraftBukkit start - Handled in calculateTarget diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index 49019d54d..9fe5c4406 100644 +index 49019d54d..bba2e164f 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -1205,6 +1205,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { } protected void c(Entity entity) { -+ if (!entity.valid) return; // Paper - Already removed, dont fire twice - this looks like it can happen even without our changes ++ if (!this.entitiesByUUID.containsKey(entity.getUniqueID()) && !entity.valid) return; // Paper - Already removed, dont fire twice - this looks like it can happen even without our changes super.c(entity); this.entitiesById.d(entity.getId()); this.entitiesByUUID.remove(entity.getUniqueID()); From c1c9d850f16509616e07b8868dfe855d4db98f64 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 10:29:14 -0400 Subject: [PATCH 3/7] Add Debug Entities option to debug dupe uuid issues Add -Ddebug.entities=true to your JVM flags to enable more logging --- ...ies-option-to-debug-dupe-uuid-issues.patch | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Spigot-Server-Patches/0336-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch diff --git a/Spigot-Server-Patches/0336-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch b/Spigot-Server-Patches/0336-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch new file mode 100644 index 000000000..c5f5055e2 --- /dev/null +++ b/Spigot-Server-Patches/0336-Add-Debug-Entities-option-to-debug-dupe-uuid-issues.patch @@ -0,0 +1,95 @@ +From b061a231214e88cde43e0c3880f779723828b2b4 Mon Sep 17 00:00:00 2001 +From: Aikar +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 f6b755863..108654d63 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 b16324e1a..994d4bbb8 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 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 + From 4a4d2996414f70dd04ba15c6929da7a92064a239 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 10:29:37 -0400 Subject: [PATCH 4/7] Add more information to Entity.toString() --- ...332-add-more-information-to-Entity.toString.patch} | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) rename Spigot-Server-Patches/{0332-add-uuid-to-Entity.toString.patch => 0332-add-more-information-to-Entity.toString.patch} (56%) diff --git a/Spigot-Server-Patches/0332-add-uuid-to-Entity.toString.patch b/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch similarity index 56% rename from Spigot-Server-Patches/0332-add-uuid-to-Entity.toString.patch rename to Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch index bddd131a9..ed65c069c 100644 --- a/Spigot-Server-Patches/0332-add-uuid-to-Entity.toString.patch +++ b/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch @@ -1,19 +1,20 @@ -From 9b99af87d227e67cfc13b271b7b1b9d6dc37e45c Mon Sep 17 00:00:00 2001 +From 9737d708c393e0fabf927551a3a2eb5c7e27ac22 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 19 Jul 2018 01:13:28 -0400 -Subject: [PATCH] add uuid to Entity.toString() +Subject: [PATCH] add more information to Entity.toString() +UUID, ticks lived, valid, dead diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index d03e7c24f..fe1ccba8d 100644 +index 80ecdb282..f6b755863 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java -@@ -2348,7 +2348,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper +@@ -2361,7 +2361,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper } public String toString() { - return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)}); -+ return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)}); // Paper - add UUID ++ return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ), this.ticksLived, this.valid, this.dead}); // Paper - add more information } public boolean isInvulnerable(DamageSource damagesource) { From a24cb4d4d60b4457d63288afd23b3bfb6d2d9a07 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 12:07:33 -0400 Subject: [PATCH 5/7] change LAST_EDIT to PAPER_LAST_EDIT for edit commands LAST_EDIT is way too generic considering it pollutes the users global environment.... --- paper | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paper b/paper index 24bc958b5..f80040c8f 100755 --- a/paper +++ b/paper @@ -99,7 +99,7 @@ case "$1" in "e" | "edit") case "$2" in "s" | "server") - export LAST_EDIT="$basedir/Paper-Server" + export PAPER_LAST_EDIT="$basedir/Paper-Server" cd "$basedir/Paper-Server" ( set -e @@ -110,7 +110,7 @@ case "$1" in ) ;; "a" | "api") - export LAST_EDIT="$basedir/Paper-API" + export PAPER_LAST_EDIT="$basedir/Paper-API" cd "$basedir/Paper-API" ( set -e @@ -121,8 +121,8 @@ case "$1" in ) ;; "c" | "continue") - cd "$LAST_EDIT" - unset LAST_EDIT + cd "$PAPER_LAST_EDIT" + unset PAPER_LAST_EDIT ( set -e From 7279362307867518880a2bb499f5da276a4dda61 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 14:46:56 -0400 Subject: [PATCH 6/7] Add more information to Entity.toString --- .../0332-add-more-information-to-Entity.toString.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch b/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch index ed65c069c..770ff6a46 100644 --- a/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch +++ b/Spigot-Server-Patches/0332-add-more-information-to-Entity.toString.patch @@ -1,4 +1,4 @@ -From 9737d708c393e0fabf927551a3a2eb5c7e27ac22 Mon Sep 17 00:00:00 2001 +From b0c9be521fc1613e6ab93cbc058b8fbf2de7068a Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 19 Jul 2018 01:13:28 -0400 Subject: [PATCH] add more information to Entity.toString() @@ -6,7 +6,7 @@ Subject: [PATCH] add more information to Entity.toString() UUID, ticks lived, valid, dead diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java -index 80ecdb282..f6b755863 100644 +index 80ecdb282..99dac412f 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -2361,7 +2361,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper @@ -14,7 +14,7 @@ index 80ecdb282..f6b755863 100644 public String toString() { - return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)}); -+ return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ), this.ticksLived, this.valid, this.dead}); // Paper - add more information ++ return String.format("%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f, cx=%d, cd=%d, tl=%d, v=%b, d=%b]", new Object[] { this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.uniqueID.toString(), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ), getChunkX(), getChunkZ(), this.ticksLived, this.valid, this.dead}); // Paper - add more information } public boolean isInvulnerable(DamageSource damagesource) { From d0cd5b3b2355d4ac9cdeeb80bb49f2510df39731 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 21 Jul 2018 14:47:05 -0400 Subject: [PATCH 7/7] Duplicate UUID Resolve Option Due to a bug in https://github.com/PaperMC/Paper/commit/2e29af3df05ec0a383f48be549d1c03200756d24 which was added all the way back in March of 2016, it was unknown (potentially not at the time) that an entity might actually change the seed of the random object. At some point, EntitySquid did start setting the seed. Due to this shared random, this caused every entity to use a Random object with a predictable seed. This has caused entities to potentially generate with the same UUID.... Over the years, servers have had entities disappear, but no sign of trouble because CraftBukkit removed the log lines indicating that something was wrong. We have fixed the root issue causing duplicate UUID's, however we now have chunk files full of entities that have the same UUID as another entity! When these chunks load, the 2nd entity will not be added to the world correctly. If that chunk loads in a different order in the future, then it will reverse and the missing one is now the one added to the world and not the other. This results in very inconsistent entity behavior. This change allows you to recover any duplicate entity by generating a new UUID for it. This also lets you delete them instead if you don't want to risk having new entities added to the world that you previously did not see. But for those who are ok with leaving this inconsistent behavior, you may use WARN or NOTHING options. It is recommended you regenerate the entities, as these were legit entities, and deserve your love. --- ...0337-Additional-Paper-Config-options.patch | 37 ++++ .../0338-Duplicate-UUID-Resolve-Option.patch | 209 ++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 Spigot-Server-Patches/0337-Additional-Paper-Config-options.patch create mode 100644 Spigot-Server-Patches/0338-Duplicate-UUID-Resolve-Option.patch diff --git a/Spigot-Server-Patches/0337-Additional-Paper-Config-options.patch b/Spigot-Server-Patches/0337-Additional-Paper-Config-options.patch new file mode 100644 index 000000000..dfb9b18af --- /dev/null +++ b/Spigot-Server-Patches/0337-Additional-Paper-Config-options.patch @@ -0,0 +1,37 @@ +From 9ac674cfb6f5f71dd61a4952c4bc7d88e3cfa3e5 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 21 Jul 2018 14:23:31 -0400 +Subject: [PATCH] Additional Paper Config options + +Have to keep as sep patch for now until 1.13, otherwise we can't merge :/ + +diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java +index 62bce1806..5a17ce3d2 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +@@ -67,6 +67,10 @@ public class PaperConfig { + readConfig(PaperConfig.class, null); + } + ++ protected static void logError(String s) { ++ Bukkit.getLogger().severe(s); ++ } ++ + protected static void log(String s) { + if (verbose) { + Bukkit.getLogger().info(s); +diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +index 50416f40a..14c8edeff 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -11,6 +11,7 @@ import org.bukkit.configuration.file.YamlConfiguration; + import org.spigotmc.SpigotWorldConfig; + + import static com.destroystokyo.paper.PaperConfig.log; ++import static com.destroystokyo.paper.PaperConfig.logError; + + public class PaperWorldConfig { + +-- +2.18.0 + diff --git a/Spigot-Server-Patches/0338-Duplicate-UUID-Resolve-Option.patch b/Spigot-Server-Patches/0338-Duplicate-UUID-Resolve-Option.patch new file mode 100644 index 000000000..5e9ec904e --- /dev/null +++ b/Spigot-Server-Patches/0338-Duplicate-UUID-Resolve-Option.patch @@ -0,0 +1,209 @@ +From 2a6d7b5cf9db036928914e854416039d7c8a14af Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Sat, 21 Jul 2018 14:27:34 -0400 +Subject: [PATCH] Duplicate UUID Resolve Option + +Due to a bug in https://github.com/PaperMC/Paper/commit/2e29af3df05ec0a383f48be549d1c03200756d24 +which was added all the way back in March of 2016, it was unknown (potentially not at the time) +that an entity might actually change the seed of the random object. + +At some point, EntitySquid did start setting the seed. Due to this shared random, this caused +every entity to use a Random object with a predictable seed. + +This has caused entities to potentially generate with the same UUID.... + +Over the years, servers have had entities disappear, but no sign of trouble +because CraftBukkit removed the log lines indicating that something was wrong. + +We have fixed the root issue causing duplicate UUID's, however we now have chunk +files full of entities that have the same UUID as another entity! + +When these chunks load, the 2nd entity will not be added to the world correctly. + +If that chunk loads in a different order in the future, then it will reverse and the +missing one is now the one added to the world and not the other. This results in very +inconsistent entity behavior. + +This change allows you to recover any duplicate entity by generating a new UUID for it. +This also lets you delete them instead if you don't want to risk having new entities added to +the world that you previously did not see. + +But for those who are ok with leaving this inconsistent behavior, you may use WARN or NOTHING options. + +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 14c8edeff..e3f6557e1 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +@@ -541,4 +541,40 @@ public class PaperWorldConfig { + log("Bed Search Radius: " + bedSearchRadius); + } + } ++ ++ public enum DuplicateUUIDMode { ++ REGEN, DELETE, NOTHING, WARN ++ } ++ public DuplicateUUIDMode duplicateUUIDMode = DuplicateUUIDMode.REGEN; ++ public void repairDuplicateUUID() { ++ String desiredMode = getString("duplicate-uuid-resolver", "regenerate").toLowerCase().trim(); ++ switch (desiredMode.toLowerCase()) { ++ case "regen": ++ case "regenerate": ++ duplicateUUIDMode = DuplicateUUIDMode.REGEN; ++ log("Duplicate UUID Resolve: Regenerate New UUID"); ++ break; ++ case "remove": ++ case "delete": ++ duplicateUUIDMode = DuplicateUUIDMode.DELETE; ++ log("Duplicate UUID Resolve: Delete Entity"); ++ break; ++ case "silent": ++ case "nothing": ++ duplicateUUIDMode = DuplicateUUIDMode.NOTHING; ++ logError("Duplicate UUID Resolve: Do Nothing (no logs) - Warning, may lose indication of bad things happening"); ++ logError("PaperMC Strongly discourages use of this setting! Triggering these messages means SOMETHING IS WRONG!"); ++ break; ++ case "log": ++ case "warn": ++ duplicateUUIDMode = DuplicateUUIDMode.WARN; ++ log("Duplicate UUID Resolve: Warn (do nothing but log it happened, may be spammy)"); ++ break; ++ default: ++ duplicateUUIDMode = DuplicateUUIDMode.WARN; ++ logError("Warning: Invalidate duplicate-uuid-resolver config " + desiredMode + " - must be one of: regen, delete, nothing, warn"); ++ log("Duplicate UUID Resolve: Warn (do nothing but log it happened, may be spammy)"); ++ break; ++ } ++ } + } +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 04adf4e3c..ea9559583 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// Paper start ++import com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode; ++import java.util.HashMap; ++import java.util.UUID; ++// Paper end + import com.destroystokyo.paper.exception.ServerInternalException; + import com.google.common.base.Predicate; + import com.google.common.collect.Maps; +@@ -31,6 +36,7 @@ public class Chunk { + public final World world; + public final int[] heightMap; + public Long scheduledForUnload; // Paper - delay chunk unloads ++ private static final Logger logger = LogManager.getLogger(); // Paper + public final int locX; + public final int locZ; + private boolean m; +@@ -658,6 +664,7 @@ public class Chunk { + if (i != this.locX || j != this.locZ) { + Chunk.e.warn("Wrong location! ({}, {}) should be ({}, {}), {}", Integer.valueOf(i), Integer.valueOf(j), Integer.valueOf(this.locX), Integer.valueOf(this.locZ), entity); + entity.die(); ++ return; // Paper + } + + int k = MathHelper.floor(entity.locY / 16.0D); +@@ -851,6 +858,37 @@ public class Chunk { + + for (int j = 0; j < i; ++j) { + List entityslice = aentityslice[j]; // Spigot ++ // Paper start ++ DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode; ++ if (mode == DuplicateUUIDMode.DELETE || mode == DuplicateUUIDMode.REGEN) { ++ Map thisChunk = new HashMap<>(); ++ for (Iterator iterator = ((List) entityslice).iterator(); iterator.hasNext(); ) { ++ Entity entity = iterator.next(); ++ Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID); ++ if (other == null) { ++ other = thisChunk.get(entity.uniqueID); ++ } ++ if (other != null) { ++ switch (mode) { ++ case REGEN: { ++ entity.setUUID(UUID.randomUUID()); ++ logger.error("Duplicate UUID found used by " + other); ++ logger.error("Regenerated a new UUID for " + entity); ++ break; ++ } ++ case DELETE: { ++ logger.error("Duplicate UUID found used by " + other); ++ logger.error("Deleting duplicate entity " + entity); ++ entity.die(); ++ iterator.remove(); ++ break; ++ } ++ } ++ } ++ thisChunk.put(entity.uniqueID, entity); ++ } ++ } ++ // Paper end + + this.world.a((Collection) entityslice); + } +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 0d3af8cb7..7188d0c99 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -2614,6 +2614,7 @@ public abstract class Entity implements ICommandListener, KeyedObject { // Paper + }); + } + ++ public void setUUID(UUID uuid) { a(uuid); } // Paper - OBFHELPER + public void a(UUID uuid) { + this.uniqueID = uuid; + this.ar = this.uniqueID.toString(); +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 994d4bbb8..1244baf45 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -42,7 +42,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { + private final PlayerChunkMap manager; + // private final Set nextTickListHash = Sets.newHashSet(); + private final HashTreeSet nextTickList = new HashTreeSet(); // CraftBukkit - HashTreeSet +- private final Map entitiesByUUID = Maps.newHashMap(); ++ public final Map entitiesByUUID = Maps.newHashMap(); // Paper + public boolean savingDisabled; + private boolean Q; + private int emptyTime; +@@ -1177,14 +1177,17 @@ 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, uuid.toString()); // CraftBukkit // Paper +- WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper +- if (DEBUG_ENTITIES) { +- if (entity1.addedToWorldStack != null) { +- entity1.addedToWorldStack.printStackTrace(); ++ if (entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) { ++ WorldServer.a.error("Keeping entity {} that already exists with UUID {}", entity1, uuid.toString()); // CraftBukkit // Paper ++ WorldServer.a.error("Duplicate entity {} will not be added to the world. See paper.yml duplicate-uuid-resolver and set this to either regen, delete or nothing to get rid of this message", entity); // Paper ++ if (DEBUG_ENTITIES) { ++ if (entity1.addedToWorldStack != null) { ++ entity1.addedToWorldStack.printStackTrace(); ++ } ++ getAddToWorldStackTrace(entity).printStackTrace(); + } +- getAddToWorldStackTrace(entity).printStackTrace(); + } ++ + return false; + } + +@@ -1206,7 +1209,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { + entity.addedToWorldStack = getAddToWorldStackTrace(entity); + } + Entity old = this.entitiesByUUID.put(entity.getUniqueID(), entity); +- if (old != null && old.getId() != entity.getId() && old.valid) { ++ if (old != null && old.getId() != entity.getId() && old.valid && entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) { + Logger logger = LogManager.getLogger(); + logger.error("Overwrote an existing entity " + old + " with " + entity); + if (DEBUG_ENTITIES) { +-- +2.18.0 +