From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Thu, 13 Aug 2020 18:56:36 -0700
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 generatoraccess which will always have the chunk available.

diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java
index 8bc8dcf7dfe79c5522bc715ad60aeaab4b1d85da..675083e3952779e43bf8cc3175ad70458a79e49c 100644
--- a/src/main/java/net/minecraft/server/EntityCat.java
+++ b/src/main/java/net/minecraft/server/EntityCat.java
@@ -292,7 +292,7 @@ public class EntityCat extends EntityTameableAnimal {
 
         WorldServer worldserver = worldaccess.getMinecraftWorld();
 
-        if (worldserver instanceof WorldServer && ((WorldServer) worldserver).getStructureManager().a(this.getChunkCoordinates(), true, StructureGenerator.SWAMP_HUT).e()) {
+        if (worldserver instanceof WorldServer && ((WorldServer) worldserver).getStructureManager().getStructureStarts(this.getChunkCoordinates(), true, StructureGenerator.SWAMP_HUT, worldaccess).e()) { // Tuinity - fix deadlock on chunk gen
             this.setCatType(10);
             this.setPersistent();
         }
diff --git a/src/main/java/net/minecraft/server/StructureManager.java b/src/main/java/net/minecraft/server/StructureManager.java
index f199368a6d78b0cd52f11ca2c8509d729b918852..2598ae3710d46c2cfd2be5d6be2a56e59ceef6ea 100644
--- a/src/main/java/net/minecraft/server/StructureManager.java
+++ b/src/main/java/net/minecraft/server/StructureManager.java
@@ -35,8 +35,13 @@ public class StructureManager {
 
     // Paper start - remove structure streams
     public java.util.List<StructureStart<?>> getFeatureStarts(SectionPosition sectionPosition, StructureGenerator<?> structureGenerator) {
+        // Tuinity start - add world parameter
+        return this.getFeatureStarts(sectionPosition, structureGenerator, null);
+    }
+    public java.util.List<StructureStart<?>> getFeatureStarts(SectionPosition sectionPosition, StructureGenerator<?> structureGenerator, IWorldReader world) {
+        // Tuinity end - add world parameter
         java.util.List<StructureStart<?>> list = new ObjectArrayList<>();
-        for (Long curLong: getLevel().getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structureGenerator)) {
+        for (Long curLong: (world == null ? getLevel() : world).getChunkAt(sectionPosition.a(), sectionPosition.c(), ChunkStatus.STRUCTURE_REFERENCES).b(structureGenerator)) { // Tuinity - fix deadlock on world gen - chunk can be unloaded while generating, so we should be using the generator's regionlimitedaccess so we always get the chunk
             SectionPosition sectionPosition1 = SectionPosition.a(new ChunkCoordIntPair(curLong), 0);
             StructureStart<?> structurestart = a(sectionPosition1, structureGenerator, getLevel().getChunkAt(sectionPosition1.a(), sectionPosition1.c(), ChunkStatus.STRUCTURE_STARTS));
             if (structurestart != null && structurestart.e()) {
@@ -65,8 +70,12 @@ public class StructureManager {
     }
 
     public StructureStart<?> a(BlockPosition blockposition, boolean flag, StructureGenerator<?> structuregenerator) {
+        // Tuinity start - add world parameter
+        return this.getStructureStarts(blockposition,flag, structuregenerator, null);
+    }
+    public StructureStart<?> getStructureStarts(BlockPosition blockposition, boolean flag, StructureGenerator<?> structuregenerator, IWorldReader world) {
         // Paper start - remove structure streams
-        for (StructureStart<?> structurestart : getFeatureStarts(SectionPosition.a(blockposition), structuregenerator)) {
+        for (StructureStart<?> structurestart : getFeatureStarts(SectionPosition.a(blockposition), structuregenerator, world)) { // Tuinity end - add world parameter
             if (structurestart.c().b(blockposition)) {
                 if (!flag) {
                     return structurestart;
