From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ishland <ishlandmc@yeah.net>
Date: Wed, 27 Jan 2021 23:35:30 +0800
Subject: [PATCH] Suspected plugins report

Added "Suspected Plugins" to Watchdog, crash reports and exception messages

diff --git a/src/main/java/net/minecraft/server/CrashReport.java b/src/main/java/net/minecraft/server/CrashReport.java
index cc6e6f245ee5e73bd570cf42381bf55ee0b364d3..2f8ec64c26f5ed239b4dd9f9532c402d7081f9ed 100644
--- a/src/main/java/net/minecraft/server/CrashReport.java
+++ b/src/main/java/net/minecraft/server/CrashReport.java
@@ -87,6 +87,8 @@ public class CrashReport {
         if (this.h != null && this.h.length > 0) {
             stringbuilder.append("-- Head --\n");
             stringbuilder.append("Thread: ").append(Thread.currentThread().getName()).append("\n");
+            org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(this.h, stringbuilder::append); // Yatopia - detailed report
+            stringbuilder.append("\n"); // Yatopia
             stringbuilder.append("Stacktrace:\n");
             StackTraceElement[] astacktraceelement = this.h;
             int i = astacktraceelement.length;
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 67e27a2931acd281803f8003069fac54245d4df6..c0be5153d117208edf69459728d57e11e26b8955 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1047,7 +1047,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
                 return;
             }
             // Paper end
-            MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
+            // Yatopia start - detailed report
+            MinecraftServer.LOGGER.error("Encountered an unexpected exception");
+            org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(throwable.getStackTrace(), MinecraftServer.LOGGER::error);
+            MinecraftServer.LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW, throwable);
+            // Yatopia end
             // Spigot Start
             if ( throwable.getCause() != null )
             {
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index ea86843fa0313da15b905cbd712c15e7b217daa4..6b071cb882c25dc2ed579d9ae48ed7d6fd816b0a 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -382,6 +382,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
             channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
             // Paper start
             } catch (Exception e) {
+                // Yatopia - detailed report
+                LOGGER.error("Encountered unexpected exception sending packets");
+                org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(e, LOGGER::error);
+                LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                // Yatopia end
                 LOGGER.error("NetworkException: " + player, e);
                 close(new ChatMessage("disconnect.genericReason", "Internal Exception: " + e.getMessage()));;
                 packet.onPacketDispatchFinish(player, null);
@@ -421,6 +426,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
                         channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
                         // Paper start
                     } catch (Exception e) {
+                        // Yatopia start - detailed report
+                        LOGGER.error("Encountered unexpected exception sending packets");
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(e, LOGGER::error);
+                        LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                        // Yatopia end
                         LOGGER.error("NetworkException: " + player, e);
                         close(new ChatMessage("disconnect.genericReason", "Internal Exception: " + e.getMessage()));;
                         packet.onPacketDispatchFinish(player, null);
@@ -456,6 +466,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
                         channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
                         // Paper start
                     } catch (Exception e) {
+                        // Yatopia start - detailed report
+                        LOGGER.error("Encountered unexpected exception sending packets");
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(e, LOGGER::error);
+                        LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                        // Yatopia end
                         LOGGER.error("NetworkException: " + player, e);
                         close(new ChatMessage("disconnect.genericReason", "Internal Exception: " + e.getMessage()));;
                         packet.onPacketDispatchFinish(player, null);
diff --git a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
index 8112b01f15c33f50fe5ec9aebf75d8091d440994..eb7e229ba4a2e4701a5a7a599f5e18da403a638b 100644
--- a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
+++ b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java
@@ -45,6 +45,11 @@ public class PlayerConnectionUtils {
                     // Paper start
                     catch (Exception e) {
                         NetworkManager networkmanager = t0.a();
+                        // Yatopia start - detailed report
+                        LOGGER.error("Encountered unexpected exception sending packets");
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(e, LOGGER::error);
+                        LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                        // Yatopia end
                         if (networkmanager.getPlayer() != null) {
                             LOGGER.error("Error whilst processing packet {} for {}[{}]", packet, networkmanager.getPlayer().getName(), networkmanager.getSocketAddress(), e);
                         } else {
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
index 0668d383db1f3a81d1053954d72678c7ac5aecec..7b9f83e63d0f9cd83a246be33af4ab91da6b2151 100644
--- a/src/main/java/net/minecraft/server/ServerConnection.java
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
@@ -153,6 +153,11 @@ public class ServerConnection {
                                 throw new ReportedException(CrashReport.a(exception, "Ticking memory connection"));
                             }
 
+                            // Yatopia start - detailed report
+                            ServerConnection.LOGGER.error("Encountered unexpected exception sending packets");
+                            org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(exception, ServerConnection.LOGGER::error);
+                            ServerConnection.LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                            // Yatopia end
                             ServerConnection.LOGGER.warn("Failed to handle packet for {}", networkmanager.getSocketAddress(), exception);
                             ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error");
 
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e6fb68f6e279eb1006f420c37fa408a0cf1fa0f3..55238930d8352ccedb963389461f119cd813aff9 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1019,6 +1019,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
                         // Paper start - Prevent tile entity and entity crashes
                         String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ();
                         System.err.println(msg);
+                        // Yatopia start - detailed report
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(throwable, System.err::println);
+                        System.err.println(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW);
+                        // Yatopia end
                         throwable.printStackTrace();
                         getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
                         // Paper end
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 0be39dac4b9dd69d7d73d86d64cf1e33e4086e81..c53531bc769ecd39c4f03b7a10c5bc6a48ace081 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -455,6 +455,7 @@ public class CraftScheduler implements BukkitScheduler {
         parsePending();
         while (isReady(currentTick)) {
             final CraftTask task = pending.remove();
+            lastSyncTask = task; // Yatopia - detailed report
             if (task.getPeriod() < CraftTask.NO_REPEATING) {
                 if (task.isSync()) {
                     runners.remove(task.getTaskId(), task);
@@ -473,12 +474,15 @@ public class CraftScheduler implements BukkitScheduler {
                         task.getTaskId(),
                         task.getOwner().getDescription().getFullName());
                     if (task.getOwner() == MINECRAFT) {
-                        net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);
+                        // Yatopia start - detailed report
+                        net.minecraft.server.MinecraftServer.LOGGER.error(msg);
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(throwable, net.minecraft.server.MinecraftServer.LOGGER::error);
+                        net.minecraft.server.MinecraftServer.LOGGER.error(org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW, throwable);
                     } else {
-                        task.getOwner().getLogger().log(
-                            Level.WARNING,
-                            msg,
-                            throwable);
+                        task.getOwner().getLogger().log(Level.SEVERE, msg);
+                        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(throwable, _msg -> task.getOwner().getLogger().log(Level.SEVERE, _msg));
+                        task.getOwner().getLogger().log(Level.SEVERE, org.yatopiamc.yatopia.api.internal.StackTraceUtils.EXCEPTION_DETAILS_BELOW, throwable);
+                        // Yatopia end
                     }
                     org.bukkit.Bukkit.getServer().getPluginManager().callEvent(
                         new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task)));
@@ -493,6 +497,7 @@ public class CraftScheduler implements BukkitScheduler {
                 // We don't need to parse pending
                 // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
             }
+            lastSyncTask = null; // Yatopia - detailed report
             final long period = task.getPeriod(); // State consistency
             if (period > 0) {
                 task.setNextRun(currentTick + period);
@@ -646,4 +651,10 @@ public class CraftScheduler implements BukkitScheduler {
         };
     }
     // Paper end
+    // Yatopia start - detailed report
+    private volatile CraftTask lastSyncTask = null;
+    public CraftTask getLastSyncTask() {
+        return lastSyncTask;
+    }
+    // Yatopia end
 }
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index 8ee165d1c752e53601254f734507370b91ad7b73..4a81dde40e2534d99001a02adac12031c26c8104 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -134,6 +134,15 @@ public class WatchdogThread extends Thread
                 log.log(Level.SEVERE, "Handling packet for connection: " + packetListener);
             }
         }
+        // Yatopia start - detailed report - Scheduler
+        if (Bukkit.getScheduler() instanceof org.bukkit.craftbukkit.scheduler.CraftScheduler) {
+            final org.bukkit.craftbukkit.scheduler.CraftScheduler scheduler = (org.bukkit.craftbukkit.scheduler.CraftScheduler) Bukkit.getScheduler();
+            final org.bukkit.craftbukkit.scheduler.CraftTask lastSyncTask = scheduler.getLastSyncTask();
+            if (lastSyncTask != null) {
+                log.log(Level.SEVERE, "Running task " + lastSyncTask.getTaskId() + " for '" + lastSyncTask.getOwner().getDescription().getFullName() + "', TaskClass: " + lastSyncTask.getTaskClass());
+            }
+        } else log.log(Level.SEVERE, "Unofficial scheduler, unable to get task information");
+        // Yatopia end
     }
     // Tuinity end - log detailed tick information
 
@@ -265,6 +274,10 @@ public class WatchdogThread extends Thread
                 log.log( Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame() );
             }
         }
+        // Yatopia start - dump plugins info
+        org.yatopiamc.yatopia.api.internal.StackTraceUtils.print(thread.getStackTrace(), msg -> log.log(Level.SEVERE, msg));
+        log.log(Level.SEVERE, "");
+        // Yatopia end
         log.log( Level.SEVERE, "\tStack:" );
         //
         for ( StackTraceElement stack : thread.getStackTrace() )
