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/world/entity/animal/EntityCat.java b/src/main/java/net/minecraft/world/entity/animal/EntityCat.java
index 054a1a74c48a3d936e45cc6b62a9fd6a90663cbc..c8f529b3fd227ce3354f442038b27cd716f57254 100644
--- a/src/main/java/net/minecraft/world/entity/animal/EntityCat.java
+++ b/src/main/java/net/minecraft/world/entity/animal/EntityCat.java
@@ -355,7 +355,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/world/level/StructureManager.java b/src/main/java/net/minecraft/world/level/StructureManager.java
index 07dcfd56af1014ad159828dd9ee2d89c2010b9f4..43418273f00f3703c7bd86586847d469af92c18f 100644
--- a/src/main/java/net/minecraft/world/level/StructureManager.java
+++ b/src/main/java/net/minecraft/world/level/StructureManager.java
@@ -46,8 +46,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()) {
@@ -76,8 +81,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;
