Merge branch 'master' into pre/1.13
* master: Duplicate UUID Resolve Option Add more information to Entity.toString change LAST_EDIT to PAPER_LAST_EDIT for edit commands Add more information to Entity.toString() Add Debug Entities option to debug dupe uuid issues Guard the Entity.SHARED_RANDOM from seed changes Create a symlink on not-windows to current minecraft decompile dir
This commit is contained in:
commit
6b63a88df0
|
@ -9,11 +9,24 @@ diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/
|
||||||
index e16579116..c0367df20 100644
|
index e16579116..c0367df20 100644
|
||||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||||
@@ -50,6 +50,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
@@ -50,6 +50,20 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
private static final int CURRENT_LEVEL = 2;
|
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) {
|
static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
|
||||||
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ index 4ac2d39c5..d6d3ffa6f 100644
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void c(Entity entity) {
|
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);
|
super.c(entity);
|
||||||
this.entitiesById.d(entity.getId());
|
this.entitiesById.d(entity.getId());
|
||||||
this.entitiesByUUID.remove(entity.getUniqueID());
|
this.entitiesByUUID.remove(entity.getUniqueID());
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
From fac0d56990f254da4f1a4b51310eaf047c9cea13 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aikar <aikar@aikar.co>
|
|
||||||
Date: Thu, 19 Jul 2018 01:13:28 -0400
|
|
||||||
Subject: [PATCH] add uuid to Entity.toString()
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
||||||
index ea42800ae..93c34a260 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
||||||
@@ -2493,7 +2493,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
- return String.format(Locale.ROOT, "%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getDisplayName().getText(), 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(Locale.ROOT, "%s[\'%s\'/%d, uuid=\'%s\', l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", new Object[] { this.getClass().getSimpleName(), this.getDisplayName().getText(), 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
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInvulnerable(DamageSource damagesource) {
|
|
||||||
--
|
|
||||||
2.18.0
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
From b0c9be521fc1613e6ab93cbc058b8fbf2de7068a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aikar <aikar@aikar.co>
|
||||||
|
Date: Thu, 19 Jul 2018 01:13:28 -0400
|
||||||
|
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..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
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 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) {
|
||||||
|
--
|
||||||
|
2.18.0
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
From b061a231214e88cde43e0c3880f779723828b2b4 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 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<NextTickListEntry> 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
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 9ac674cfb6f5f71dd61a4952c4bc7d88e3cfa3e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aikar <aikar@aikar.co>
|
||||||
|
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
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
From 2a6d7b5cf9db036928914e854416039d7c8a14af 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
|
||||||
|
|
||||||
|
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<UUID, Entity> thisChunk = new HashMap<>();
|
||||||
|
+ for (Iterator<Entity> iterator = ((List<Entity>) 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<NextTickListEntry> nextTickListHash = Sets.newHashSet();
|
||||||
|
private final HashTreeSet<NextTickListEntry> nextTickList = new HashTreeSet<NextTickListEntry>(); // CraftBukkit - HashTreeSet
|
||||||
|
- private final Map<UUID, Entity> entitiesByUUID = Maps.newHashMap();
|
||||||
|
+ public final Map<UUID, Entity> 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
|
||||||
|
|
8
paper
8
paper
|
@ -99,7 +99,7 @@ case "$1" in
|
||||||
"e" | "edit")
|
"e" | "edit")
|
||||||
case "$2" in
|
case "$2" in
|
||||||
"s" | "server")
|
"s" | "server")
|
||||||
export LAST_EDIT="$basedir/Paper-Server"
|
export PAPER_LAST_EDIT="$basedir/Paper-Server"
|
||||||
cd "$basedir/Paper-Server"
|
cd "$basedir/Paper-Server"
|
||||||
(
|
(
|
||||||
set -e
|
set -e
|
||||||
|
@ -110,7 +110,7 @@ case "$1" in
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
"a" | "api")
|
"a" | "api")
|
||||||
export LAST_EDIT="$basedir/Paper-API"
|
export PAPER_LAST_EDIT="$basedir/Paper-API"
|
||||||
cd "$basedir/Paper-API"
|
cd "$basedir/Paper-API"
|
||||||
(
|
(
|
||||||
set -e
|
set -e
|
||||||
|
@ -121,8 +121,8 @@ case "$1" in
|
||||||
)
|
)
|
||||||
;;
|
;;
|
||||||
"c" | "continue")
|
"c" | "continue")
|
||||||
cd "$LAST_EDIT"
|
cd "$PAPER_LAST_EDIT"
|
||||||
unset LAST_EDIT
|
unset PAPER_LAST_EDIT
|
||||||
(
|
(
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|
|
@ -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 <zach.brown@destroystokyo.com>
|
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||||
Date: Fri, 16 Dec 2016 22:10:35 -0600
|
Date: Fri, 16 Dec 2016 22:10:35 -0600
|
||||||
Subject: [PATCH] Vanished players don't have rights
|
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
|
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
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||||
+++ b/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 double f = 1.0D;
|
||||||
private static int entityCount;
|
private static int entityCount;
|
||||||
private int id;
|
private int id;
|
||||||
|
|
|
@ -6,9 +6,9 @@ PS1="$"
|
||||||
basedir="$(cd "$1" && pwd -P)"
|
basedir="$(cd "$1" && pwd -P)"
|
||||||
workdir="$basedir/work"
|
workdir="$basedir/work"
|
||||||
minecraftversion=$(cat "$workdir/BuildData/info.json" | grep minecraftVersion | cut -d '"' -f 4)
|
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"
|
decompiledir="$workdir/Minecraft/$minecraftversion"
|
||||||
classdir="$decompiledir/classes"
|
classdir="$decompiledir/classes"
|
||||||
|
|
||||||
echo "Extracting NMS classes..."
|
echo "Extracting NMS classes..."
|
||||||
if [ ! -d "$classdir" ]; then
|
if [ ! -d "$classdir" ]; then
|
||||||
mkdir -p "$classdir"
|
mkdir -p "$classdir"
|
||||||
|
@ -30,4 +30,13 @@ if [ ! -d "$decompiledir/net/minecraft/server" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
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
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue