mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-22 08:57:35 +01:00
dc684c60d1
The new behavior of disconnect to block the current thread until the disconnect succeeded is better than throwing it off to happen at some point
209 lines
12 KiB
Diff
209 lines
12 KiB
Diff
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
|
|
index 8b5eabea1a0926c22b58ef8761caee3a06aa5ee0..53fdf4e104f36a2bd88fdf26d8c68cd3daf61574 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1224,6 +1224,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
// CraftBukkit start
|
|
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
|
+ entity.generation = false; // Paper - Don't fire sync event during generation; Reset flag if it was added during a ServerLevel generation process
|
|
// Paper start - extra debug info
|
|
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
|
|
index 9afb2154a85da83ed50b1c80c21f03e4843ce63c..e4ad97071ed0e82fc910c34e700c6c6eee99deea 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -625,7 +625,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
if (pose == this.getPose()) {
|
|
return;
|
|
}
|
|
- this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
|
|
+ // Paper start - Don't fire sync event during generation
|
|
+ if (!this.generation) {
|
|
+ this.level.getCraftServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[pose.ordinal()]));
|
|
+ }
|
|
+ // Paper end - Don't fire sync event during generation
|
|
// 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
|
|
index 5fb3279342506611882b5780cfbee0371919c93c..b98f9246b60daf31460f41ce214dfa7c011f5684 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
@@ -592,9 +592,15 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
|
}
|
|
|
|
public static Optional<Entity> create(CompoundTag nbt, Level world) {
|
|
+ // Paper start - Don't fire sync event during generation
|
|
+ return create(nbt, world, false);
|
|
+ }
|
|
+ public static Optional<Entity> create(CompoundTag nbt, Level world, boolean generation) {
|
|
+ // Paper end - Don't fire sync event during generation
|
|
return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> {
|
|
return entitytypes.create(world);
|
|
}), (entity) -> {
|
|
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
|
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
|
|
index 9a2b874594e2f04f59b7d2be389223604d56219a..3f788e88604b77761c5add39450cf1640604c0f0 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -1137,6 +1137,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
|
}
|
|
|
|
public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause) {
|
|
+ // Paper start - Don't fire sync event during generation
|
|
+ return this.addEffect(mobeffect, entity, cause, true);
|
|
+ }
|
|
+ public boolean addEffect(MobEffectInstance mobeffect, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
|
+ // Paper end - Don't fire sync event during generation
|
|
// org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
|
|
if (this.isTickingEffects) {
|
|
this.effectsToProcess.add(new ProcessableEffect(mobeffect, cause));
|
|
@@ -1156,10 +1161,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
|
override = new MobEffectInstance(mobeffect1).update(mobeffect);
|
|
}
|
|
|
|
+ if (fireEvent) { // Paper - Don't fire sync event during generation
|
|
EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent(this, mobeffect1, mobeffect, cause, override);
|
|
+ override = event.isOverride(); // Paper - Don't fire sync event during generation
|
|
if (event.isCancelled()) {
|
|
return false;
|
|
}
|
|
+ } // Paper - Don't fire sync event during generation
|
|
// CraftBukkit end
|
|
|
|
if (mobeffect1 == null) {
|
|
@@ -1168,7 +1176,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
|
flag = true;
|
|
mobeffect.onEffectAdded(this);
|
|
// CraftBukkit start
|
|
- } else if (event.isOverride()) {
|
|
+ } else if (override) { // Paper - Don't fire sync event during generation
|
|
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
|
|
index 6006480d9f6d60bb7b5628eabe6740013066cde4..f0127f1b55999aa4a841341ad02cbcde45702b50 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
|
|
@@ -172,7 +172,7 @@ public class Spider extends Monster {
|
|
Holder<MobEffect> holder = entityspider_groupdataspider.effect;
|
|
|
|
if (holder != null) {
|
|
- this.addEffect(new MobEffectInstance(holder, -1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN); // CraftBukkit
|
|
+ this.addEffect(new MobEffectInstance(holder, -1), null, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.SPIDER_SPAWN, world instanceof net.minecraft.server.level.ServerLevel); // CraftBukkit
|
|
}
|
|
}
|
|
|
|
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
|
|
index cf8258e8d46ca7286a66c38fa24af369bd9a279f..0555abfda468c343af8244a122ebe769e70a0292 100644
|
|
--- 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
|
|
@@ -525,7 +525,7 @@ public class StructureTemplate {
|
|
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) {
|
|
// CraftBukkit start
|
|
// try {
|
|
- return EntityType.create(nbt, world.getLevel());
|
|
+ return EntityType.create(nbt, world.getLevel(), true); // Paper - Don't fire sync event during generation
|
|
// } 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
|
|
index 0794d92c42b0db6b367505ae28f09f1fd39fa312..cd7f1309cf01a5f01a28aded03a36fe15adb1756 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/DelegatedGeneratorAccess.java
|
|
@@ -92,15 +92,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);
|
|
- }
|
|
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
|
|
+ // @Override
|
|
+ // public void addFreshEntityWithPassengers(Entity arg0, CreatureSpawnEvent.SpawnReason arg1) {
|
|
+ // this.handle.addFreshEntityWithPassengers(arg0, arg1);
|
|
+ // }
|
|
+ //
|
|
+ // @Override
|
|
+ // public void addFreshEntityWithPassengers(Entity entity) {
|
|
+ // this.handle.addFreshEntityWithPassengers(entity);
|
|
+ // }
|
|
+ // Paper end - Don't fire sync event during generation; don't override these methods
|
|
|
|
@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
|
|
index 35ecf6f824aca56a20280dd683123df1d0c7d66e..1d1fdcf10498c421f106158254e052da6d68d8a5 100644
|
|
--- 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);
|
|
- }
|
|
+ // Paper start - Don't fire sync event during generation; don't override these methods so all entities are run through addFreshEntity
|
|
+ // @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);
|
|
+ // }
|
|
+ // Paper end - Don't fire sync event during generation; don't override these methods
|
|
|
|
public boolean setCraftBlock(BlockPos position, CraftBlockState craftBlockState, int i, int j) {
|
|
if (this.structureTransformer != null) {
|