1
0
Fork 0
mirror of https://github.com/PaperMC/Paper.git synced 2025-02-17 02:34:30 +01:00

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.
This commit is contained in:
Spottedleaf 2022-03-12 06:31:13 -08:00
parent df181fa967
commit 2de1053b58
2 changed files with 47 additions and 0 deletions
paper-server/patches/sources/net/minecraft/world

View file

@ -13,6 +13,15 @@
Objects.requireNonNull(iregistry);
optional.flatMap(iregistry::get).ifPresent(this::setVariant);
@@ -365,7 +365,7 @@
BuiltInRegistries.CAT_VARIANT.getRandomElementOf(tagkey, world.getRandom()).ifPresent(this::setVariant);
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((Holder) BuiltInRegistries.CAT_VARIANT.getOrThrow(CatVariant.ALL_BLACK));
this.setPersistenceRequired();
}
@@ -462,7 +462,7 @@
}

View file

@ -0,0 +1,38 @@
--- a/net/minecraft/world/level/StructureManager.java
+++ b/net/minecraft/world/level/StructureManager.java
@@ -48,7 +48,12 @@
}
public List<StructureStart> startsForStructure(ChunkPos pos, Predicate<Structure> predicate) {
- Map<Structure, LongSet> 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<StructureStart> startsForStructure(ChunkPos pos, Predicate<Structure> predicate, @Nullable ServerLevelAccessor levelAccessor) {
+ Map<Structure, LongSet> map = (levelAccessor == null ? this.level : levelAccessor).getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences();
+ // Paper end - Fix swamp hut cat generation deadlock
Builder<StructureStart> builder = ImmutableList.builder();
for (Entry<Structure, LongSet> entry : map.entrySet()) {
@@ -116,10 +121,20 @@
}
public StructureStart getStructureWithPieceAt(BlockPos pos, Predicate<Holder<Structure>> predicate) {
+ // Paper start - Fix swamp hut cat generation deadlock
+ return this.getStructureWithPieceAt(pos, predicate, null);
+ }
+
+ public StructureStart getStructureWithPieceAt(BlockPos pos, TagKey<Structure> tag, @Nullable ServerLevelAccessor levelAccessor) {
+ return this.getStructureWithPieceAt(pos, structure -> structure.is(tag), levelAccessor);
+ }
+
+ public StructureStart getStructureWithPieceAt(BlockPos pos, Predicate<Holder<Structure>> predicate, @Nullable ServerLevelAccessor levelAccessor) {
+ // Paper end - Fix swamp hut cat generation deadlock
Registry<Structure> registry = this.registryAccess().lookupOrThrow(Registries.STRUCTURE);
for (StructureStart structureStart : this.startsForStructure(
- new ChunkPos(pos), structure -> registry.get(registry.getId(structure)).map(predicate::test).orElse(false)
+ new ChunkPos(pos), structure -> registry.get(registry.getId(structure)).map(predicate::test).orElse(false), levelAccessor // Paper - Fix swamp hut cat generation deadlock
)) {
if (this.structureHasPieceAt(pos, structureStart)) {
return structureStart;