2024-01-04 21:55:01 +01:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 23 Nov 2023 10:33:25 -0800
Subject: [PATCH] Don't fire sync events during worldgen
Fixes EntityPotionEffectEvent
Fixes EntityPoseChangeEvent
Asynchronous chunk generation provides an opportunity for things
to happen async that previously fired synchronous-only events. This
patch is for mitigating those issues by various methods.
Also fixes correctly marking/clearing the entity generation flag.
This patch sets the generation flag anytime an entity is created
via StructureTemplate before loading from NBT to catch uses of
the flag during the loading logic. This patch clears the generation
flag from an entity when added to a ServerLevel for the situation
where generation happened directly to a ServerLevel and the
entity still has the flag set.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
2024-01-18 18:52:00 +01:00
index 51f14e0c22dd66d8e33c132974139922fcadf095..9801b283da75aa63d7eba33d08322285c86c241c 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
2024-01-12 21:58:54 +01:00
@@ -1681,6 +1681,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
2024-01-04 21:55:01 +01:00
// CraftBukkit start
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
2024-01-13 18:34:33 +01:00
+ entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process
2024-01-04 21:55:01 +01:00
// Paper start
if (entity.valid) {
MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
2024-01-18 18:52:00 +01:00
index 5c2c9a8f22cce8994cecbef7a3ca5fdc0a89a7ae..96d2fa0278ada7fb706a39ca2a93f5259239229c 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
2024-01-14 10:46:04 +01:00
@@ -713,7 +713,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
2024-01-04 21:55:01 +01:00
if (pose == this.getPose()) {
return;
}
- this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
2024-01-13 18:34:33 +01:00
+ // Paper start - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
+ if (!this.generation) {
+ this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
+ }
2024-01-13 18:34:33 +01:00
+ // Paper end - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
// CraftBukkit end
this.entityData.set(Entity.DATA_POSE, pose);
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
2024-01-16 12:41:40 +01:00
index 82695b6f25011a315027bd7a5cb305af31663d4a..d362a06d0600003d40f632eac602ff552cafb9da 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -588,9 +588,15 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
}
public static Optional<Entity> create(CompoundTag nbt, Level world) {
2024-01-13 18:34:33 +01:00
+ // Paper start - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
+ return create(nbt, world, false);
+ }
+ public static Optional<Entity> create(CompoundTag nbt, Level world, boolean generation) {
2024-01-13 18:34:33 +01:00
+ // Paper end - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> {
return entitytypes.create(world);
}), (entity) -> {
2024-01-13 18:34:33 +01:00
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
entity.load(nbt);
}, () -> {
EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id"));
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
2024-01-18 18:52:00 +01:00
index 6f7e05c6d73999613ae5980ec70b841299d021b1..8713ee8ff8a2b269c6d138e7f483a80fa2521793 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
2024-01-16 12:41:40 +01:00
@@ -1134,6 +1134,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
2024-01-04 21:55:01 +01:00
}
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
2024-01-13 18:34:33 +01:00
+ // Paper start - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
+ return this.addEffect(mobeffect, entity, cause, true);
+ }
+ public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
2024-01-13 18:34:33 +01:00
+ // Paper end - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
// org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
if (this.isTickingEffects) {
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
2024-01-16 12:41:40 +01:00
@@ -1153,10 +1158,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
2024-01-04 21:55:01 +01:00
override = new MobEffectInstance(mobeffect1).update(mobeffect);
}
2024-01-13 18:34:33 +01:00
+ if (fireEvent) { // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, mobeffect1, mobeffect, cause, override);
2024-01-13 18:34:33 +01:00
+ override = event.isOverride(); // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
if (event.isCancelled()) {
return false;
}
2024-01-13 18:34:33 +01:00
+ } // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
// CraftBukkit end
if (mobeffect1 == null) {
2024-01-16 12:41:40 +01:00
@@ -1164,7 +1172,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
2024-01-04 21:55:01 +01:00
this.onEffectAdded(mobeffect, entity);
flag = true;
// CraftBukkit start
- } else if (event.isOverride()) {
2024-01-13 18:34:33 +01:00
+ } else if (override) { // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
mobeffect1.update(mobeffect);
this.onEffectUpdated(mobeffect1, true, entity);
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
2024-01-13 18:34:33 +01:00
index 5a9f4a022c8e7a0804543335bfe91e1328d040e6..8094c133f9e934c98eee09738220bacd87a0a364 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
@@ -182,7 +182,7 @@ public class Spider extends Monster {
MobEffect mobeffectlist = entityspider_groupdataspider.effect;
if (mobeffectlist != null) {
- this.addEffect(new MobEffectInstance(mobeffectlist, -1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN); // CraftBukkit
2024-01-13 18:34:33 +01:00
+ this.addEffect(new MobEffectInstance(mobeffectlist, -1), null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN, world instanceof net.minecraft.server.level.ServerLevel); // CraftBukkit // Paper - Don't fire sync event during generation; only if this is happening in a ServerLevel
2024-01-04 21:55:01 +01:00
}
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
2024-01-18 18:52:00 +01:00
index 0540929bd362b266295ea6770ce2fb351b614463..4aacb6675e8fe577749fa83ad471eb6e6cf930df 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
@@ -518,7 +518,7 @@ public class StructureTemplate {
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) {
// CraftBukkit start
// try {
- return EntityType.create(nbt, world.getLevel());
2024-01-13 18:34:33 +01:00
+ return EntityType.create(nbt, world.getLevel(), true); // Paper - Don't fire sync event during generation
2024-01-04 21:55:01 +01:00
// } catch (Exception exception) {
// return Optional.empty();
// }
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
2024-01-13 18:34:33 +01:00
index a650411e3fa7e2a045ac55502c77028be348acf1..86a20c91beff6b27e6ec886e49ba902b216106f2 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
@@ -93,15 +93,17 @@ public abstract class DelegatedGeneratorAccess implements WorldGenLevel {
return this.handle.getLevel();
}
- @Override
- public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
- this.handle.addFreshEntityWithPassengers(arg0, arg1);
- }
-
- @Override
- public void addFreshEntityWithPassengers(Entity entity) {
- this.handle.addFreshEntityWithPassengers(entity);
- }
2024-01-13 18:34:33 +01:00
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
2024-01-04 21:55:01 +01:00
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
+ // this.handle.addFreshEntityWithPassengers(arg0, arg1);
+ // }
+ //
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity entity) {
+ // this.handle.addFreshEntityWithPassengers(entity);
+ // }
2024-01-13 18:34:33 +01:00
+ // Paper end - Don't fire sync event during generation; don't override these methods
2024-01-04 21:55:01 +01:00
@Override
public ServerLevel getMinecraftWorld() {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
2024-01-13 18:34:33 +01:00
index b4b297945fb601701aac845d09e88fb74b09c3fa..7482dfe64458320d44089c0778591694202e9f70 100644
2024-01-04 21:55:01 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java
@@ -39,21 +39,23 @@ public class TransformerGeneratorAccess extends DelegatedGeneratorAccess {
return super.addFreshEntity(arg0, arg1);
}
- @Override
- public void addFreshEntityWithPassengers(Entity entity) {
- if (this.structureTransformer != null && !this.structureTransformer.transformEntity(entity)) {
- return;
- }
- super.addFreshEntityWithPassengers(entity);
- }
-
- @Override
- public void addFreshEntityWithPassengers(Entity arg0, SpawnReason arg1) {
- if (this.structureTransformer != null && !this.structureTransformer.transformEntity(arg0)) {
- return;
- }
- super.addFreshEntityWithPassengers(arg0, arg1);
- }
2024-01-13 18:34:33 +01:00
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
2024-01-04 21:55:01 +01:00
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity entity) {
+ // if (this.structureTransformer != null && !this.structureTransformer.transformEntity(entity)) {
+ // return;
+ // }
+ // super.addFreshEntityWithPassengers(entity);
+ // }
+ //
+ // @Override
+ // public void addFreshEntityWithPassengers(Entity arg0, SpawnReason arg1) {
+ // if (this.structureTransformer != null && !this.structureTransformer.transformEntity(arg0)) {
+ // return;
+ // }
+ // super.addFreshEntityWithPassengers(arg0, arg1);
+ // }
2024-01-13 18:34:33 +01:00
+ // Paper end - Don't fire sync event during generation; don't override these methods
2024-01-04 21:55:01 +01:00
public boolean setCraftBlock(BlockPos position, CraftBlockState craftBlockState, int i, int j) {
if (this.structureTransformer != null) {