From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 12 Mar 2022 06:31:13 -0800 Subject: [PATCH] Fix swamp hut cat generation deadlock The worldgen thread will attempt to get structure references via the world's getChunkAt method, which is fine if the gen is not cancelled - but if the chunk was unloaded, the call will block indefinitely. Instead of using the world state, we use the already supplied ServerLevelAccessor which will always have the chunk available. diff --git a/src/main/java/net/minecraft/world/entity/animal/Cat.java b/src/main/java/net/minecraft/world/entity/animal/Cat.java index 534630b0161c8d869e49e7a59572193550be0671..7dfd2b17e82a80683af28779d0bd8f64a909c3b6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Cat.java +++ b/src/main/java/net/minecraft/world/entity/animal/Cat.java @@ -364,7 +364,7 @@ public class Cat extends TamableAnimal implements VariantHolder { }); ServerLevel worldserver = world.getLevel(); - if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK).isValid()) { + if (worldserver.structureManager().getStructureWithPieceAt(this.blockPosition(), StructureTags.CATS_SPAWN_AS_BLACK, world).isValid()) { // Paper - Fix swamp hut cat generation deadlock this.setVariant((CatVariant) BuiltInRegistries.CAT_VARIANT.getOrThrow(CatVariant.ALL_BLACK)); this.setPersistenceRequired(); } diff --git a/src/main/java/net/minecraft/world/level/StructureManager.java b/src/main/java/net/minecraft/world/level/StructureManager.java index 09e0c6b6bddcba2f4a59838ac63cda3188f71e41..07eb481380e8fd4e492f36342ba633579c1b624e 100644 --- a/src/main/java/net/minecraft/world/level/StructureManager.java +++ b/src/main/java/net/minecraft/world/level/StructureManager.java @@ -46,7 +46,12 @@ public class StructureManager { } public List startsForStructure(ChunkPos pos, Predicate predicate) { - Map map = this.level.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + // Paper start - Fix swamp hut cat generation deadlock + return this.startsForStructure(pos, predicate, null); + } + public List startsForStructure(ChunkPos pos, Predicate predicate, @Nullable ServerLevelAccessor levelAccessor) { + Map map = (levelAccessor == null ? this.level : levelAccessor).getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + // Paper end - Fix swamp hut cat generation deadlock Builder builder = ImmutableList.builder(); for (Entry entry : map.entrySet()) { @@ -111,10 +116,15 @@ public class StructureManager { } public StructureStart getStructureWithPieceAt(BlockPos pos, TagKey structureTag) { + // Paper start - Fix swamp hut cat generation deadlock + return this.getStructureWithPieceAt(pos, structureTag, null); + } + public StructureStart getStructureWithPieceAt(BlockPos pos, TagKey structureTag, @Nullable ServerLevelAccessor levelAccessor) { + // Paper end - Fix swamp hut cat generation deadlock Registry registry = this.registryAccess().registryOrThrow(Registries.STRUCTURE); for (StructureStart structureStart : this.startsForStructure( - new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(reference -> reference.is(structureTag)).orElse(false) + new ChunkPos(pos), structure -> registry.getHolder(registry.getId(structure)).map(reference -> reference.is(structureTag)).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock )) { if (this.structureHasPieceAt(pos, structureStart)) { return structureStart;