mirror of
https://github.com/PaperMC/Paper.git
synced 2024-09-12 06:58:11 +02:00
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 30885166 Update to Minecraft 1.16.4 CraftBukkit Changes: 3af81c71 Update to Minecraft 1.16.4 Spigot Changes: f011ca24 Update to Minecraft 1.16.4 Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com>
80 lines
3.7 KiB
Diff
80 lines
3.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Sun, 29 Mar 2020 18:26:14 -0400
|
|
Subject: [PATCH] Ensure Entity is never double registered
|
|
|
|
If something calls register twice, and the world is ticking, it could be
|
|
enqueued to add twice.
|
|
|
|
Vs behavior of non ticking of just overwriting state.
|
|
|
|
We will now simply log a warning when this happens instead of crashing the server.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index d728a3aae38c083fe8dfa28a8b8460545e99bcb9..e98b247df2f5b34bd1f15a483c8da2f76aa96384 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -59,6 +59,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
}
|
|
|
|
// Paper start
|
|
+ boolean isQueuedForRegister = false;
|
|
public static Random SHARED_RANDOM = new Random() {
|
|
private boolean locked = false;
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index 784381e117ea9e39f3dabedba35daf0a41b119c5..2b7b7a8282424ad3c99824af99b5527a59c48bdb 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -535,6 +535,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
Entity entity2;
|
|
|
|
while ((entity2 = (Entity) this.entitiesToAdd.poll()) != null) {
|
|
+ if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers
|
|
this.registerEntity(entity2);
|
|
}
|
|
|
|
@@ -1290,6 +1291,19 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
|
|
public void unregisterEntity(Entity entity) {
|
|
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
|
|
+ // Paper start - fix entity registration issues
|
|
+ if (entity instanceof EntityComplexPart) {
|
|
+ // Usually this is a no-op for complex parts, and ID's should be removed, but go ahead and remove it anyways
|
|
+ // Dragon parts are handled special in register. they don't receive a valid = true or register by UUID etc.
|
|
+ this.entitiesById.remove(entity.getId(), entity);
|
|
+ return;
|
|
+ }
|
|
+ if (!entity.valid) {
|
|
+ // Someone called remove before we ever got added, cancel the add.
|
|
+ entity.isQueuedForRegister = false;
|
|
+ return;
|
|
+ }
|
|
+ // Paper end
|
|
// Spigot start
|
|
if ( entity instanceof EntityHuman )
|
|
{
|
|
@@ -1356,9 +1370,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
|
|
private void registerEntity(Entity entity) {
|
|
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
|
|
+ // Paper start - don't double enqueue entity registration
|
|
+ //noinspection ObjectEquality
|
|
+ if (this.entitiesById.get(entity.getId()) == entity) {
|
|
+ LOGGER.error(entity + " was already registered!");
|
|
+ new Throwable().printStackTrace();
|
|
+ return;
|
|
+ }
|
|
+ // Paper end
|
|
if (this.tickingEntities) {
|
|
- this.entitiesToAdd.add(entity);
|
|
+ if (!entity.isQueuedForRegister) { // Paper
|
|
+ this.entitiesToAdd.add(entity);
|
|
+ entity.isQueuedForRegister = true; // Paper
|
|
+ }
|
|
} else {
|
|
+ entity.isQueuedForRegister = false; // Paper
|
|
this.entitiesById.put(entity.getId(), entity);
|
|
if (entity instanceof EntityEnderDragon) {
|
|
EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eJ();
|