From f97766019adfc6f321ed068b43790e8b96d17035 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 19 Jan 2025 19:08:14 -0500 Subject: [PATCH] Prevent sculk events in addPassenger from deadlocking the game during worldgen This seems to be a vanilla bug when spawning entities that ride other entities Related: #510 --- .../bugfix/chunk_deadlock/EntityMixin.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/EntityMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/EntityMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/EntityMixin.java new file mode 100644 index 00000000..71951d23 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/EntityMixin.java @@ -0,0 +1,31 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock; + +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.gameevent.GameEvent; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Entity.class) +public class EntityMixin { + /** + * @author embeddedt + * @reason When an entity is added to the world via the worldgen load path (ChunkMap#postLoadProtoChunk calling + * ServerLevel#addWorldGenChunkEntities), attempts to add a passenger result in a deadlock when the sculk event + * tries to raytrace blocks. To fix this, we skip firing the sculk event if the chunk the entity is within is not + * loaded. + */ + @WrapWithCondition(method = "addPassenger", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;gameEvent(Lnet/minecraft/world/level/gameevent/GameEvent;Lnet/minecraft/world/entity/Entity;)V")) + private boolean onlyAddIfSelfChunkLoaded(Entity instance, GameEvent event, Entity entity) { + var chunkPos = instance.chunkPosition(); + if (instance.level() instanceof ServerLevel serverLevel && serverLevel.getChunkSource().getChunkNow(chunkPos.x, chunkPos.z) == null) { + ModernFix.LOGGER.warn("Skipped emitting ENTITY_MOUNT game event for entity {} as it would cause deadlock", instance.toString()); + return false; + } else { + return true; + } + } +}