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.
This commit is contained in:
parent
2ec0274b88
commit
bc351f6eff
1 changed files with 83 additions and 0 deletions
|
@ -0,0 +1,83 @@
|
||||||
|
From e4dec7b8e9738cefe23b9b032b0ec6fabdbbcc1b 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 8da54c68cc..eb706f8636 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 5ba46fca55..9cb22eef56 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||||
|
@@ -519,7 +519,7 @@ public class WorldServer extends World {
|
||||||
|
this.tickingEntities = false;
|
||||||
|
|
||||||
|
try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings
|
||||||
|
- while ((entity = (Entity) this.entitiesToAdd.poll()) != null) {
|
||||||
|
+ while ((entity = (Entity) this.entitiesToAdd.poll()) != null && entity.isQueuedForRegister) { // Paper - ignore cancelled registers
|
||||||
|
this.registerEntity(entity);
|
||||||
|
}
|
||||||
|
} // Paper - timings
|
||||||
|
@@ -1329,6 +1329,19 @@ public class WorldServer extends World {
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
@@ -1390,9 +1403,21 @@ public class WorldServer extends World {
|
||||||
|
|
||||||
|
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).eo();
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
Loading…
Reference in a new issue