Files
Paper/patches/server-remapped/Ensure-Entity-is-never-double-registered.patch
MiniDigger | Martin 95d25d98e8 Move patches around
2021-06-11 14:02:28 +02:00

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/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
Entity entity2;
while ((entity2 = (Entity) this.toAddAfterTick.poll()) != null) {
+ if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers
this.add(entity2);
}
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
public void onEntityRemoved(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
+ // Paper start - fix entity registration issues
+ if (entity instanceof EnderDragonPart) {
+ // 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 Player )
{
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
private void add(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.toAddAfterTick.add(entity);
+ if (!entity.isQueuedForRegister) { // Paper
+ this.toAddAfterTick.add(entity);
+ entity.isQueuedForRegister = true; // Paper
+ }
} else {
+ entity.isQueuedForRegister = false; // Paper
this.entitiesById.put(entity.getId(), entity);
if (entity instanceof EnderDragon) {
EnderDragonPart[] aentitycomplexpart = ((EnderDragon) entity).getSubEntities();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
}
// Paper start
+ public boolean isQueuedForRegister = false;
public static Random SHARED_RANDOM = new Random() {
private boolean locked = false;
@Override