From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Thu, 10 Dec 2020 14:38:58 -0800
Subject: [PATCH] Do not load chunks during a crash report

This causes deadlocks in some cases when generating
crash reports.

Fixes https://github.com/Spottedleaf/Tuinity/issues/215

diff --git a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
index 7511e38130f38703164395a670f12d1af648ff04..e602efcb3fad390bb6bff1055e782bba909d7694 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
@@ -37,7 +37,7 @@ public class CraftCrashReport implements CrashReportCallable<Object> {
             value.append("\n   Force Loaded Chunks: {");
             for (World world : Bukkit.getWorlds()) {
                 value.append(' ').append(world.getName()).append(": {");
-                for (Map.Entry<Plugin, Collection<Chunk>> entry : world.getPluginChunkTickets().entrySet()) {
+                for (Map.Entry<Plugin, Collection<net.minecraft.server.ChunkCoordIntPair>> entry : ((CraftWorld)world).getPluginChunkTicketsCoordinates().entrySet()) { // Tuinity - do not load chunks in crash reports
                     value.append(' ').append(entry.getKey().getDescription().getFullName()).append(": ").append(Integer.toString(entry.getValue().size())).append(',');
                 }
                 value.append("},");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index eb90c0802e3ca344885ee14fd852e963a66f5f33..3e54e643d28ced3074c4b044bc8a2238de05ccc2 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -720,6 +720,30 @@ public class CraftWorld implements World {
         return ret.entrySet().stream().collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, (entry) -> entry.getValue().build()));
     }
 
+    // Tuinity start - don't load chunks for crash reports
+    public Map<Plugin, Collection<ChunkCoordIntPair>> getPluginChunkTicketsCoordinates() {
+        // Copied from above
+        Map<Plugin, ImmutableList.Builder<ChunkCoordIntPair>> ret = new HashMap<>();
+        ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager;
+
+        for (Long2ObjectMap.Entry<ArraySetSorted<Ticket<?>>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) {
+            long chunkKey = chunkTickets.getLongKey();
+            ArraySetSorted<Ticket<?>> tickets = chunkTickets.getValue();
+
+            ChunkCoordIntPair chunk = new ChunkCoordIntPair(chunkKey);
+            for (Ticket<?> ticket : tickets) {
+                if (ticket.getTicketType() != TicketType.PLUGIN_TICKET) {
+                    continue;
+                }
+
+                ret.computeIfAbsent((Plugin) ticket.identifier, (key) -> ImmutableList.builder()).add(chunk);
+            }
+        }
+
+        return ret.entrySet().stream().collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, (entry) -> entry.getValue().build()));
+    }
+    // Tuinity end - don't load chunks for crash reports
+
     @Override
     public boolean isChunkForceLoaded(int x, int z) {
         return getHandle().getForceLoadedChunks().contains(ChunkCoordIntPair.pair(x, z));
