| 1 |  |  | package de.pewpewproject.lasertag.mixin; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | import com.google.common.collect.Streams; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | import com.mojang.logging.LogUtils; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | import de.pewpewproject.lasertag.LasertagMod; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | import net.minecraft.Bootstrap; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | import net.minecraft.server.dedicated.DedicatedServerWatchdog; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | import net.minecraft.util.Util; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | import net.minecraft.util.crash.CrashReport; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | import net.minecraft.util.crash.CrashReportSection; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | import net.minecraft.util.registry.RegistryKey; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | import net.minecraft.world.GameRules; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | import org.spongepowered.asm.mixin.Mixin; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | import org.spongepowered.asm.mixin.injection.At; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | import org.spongepowered.asm.mixin.injection.Inject; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | import java.io.File; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | import java.lang.management.ManagementFactory; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | import java.lang.management.ThreadInfo; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | import java.lang.management.ThreadMXBean; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | import java.util.Locale; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | import java.util.stream.Collectors; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |  * Mixin into the DedicatedServerWatchdog.class to disable the watchdog during map load | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  * @author Étienne Muser | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 29 |  |  |  */ | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  | @Mixin(DedicatedServerWatchdog.class) | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  | public abstract class DedicatedServerWatchdogMixin { | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |     private boolean isIgnoring = false; | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |     @Inject(method = "run()V", at = @At("HEAD"), cancellable = true) | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |     private void runOverride(CallbackInfo ci) { | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         var thisWD = ((DedicatedServerWatchdog) (Object) this); | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |         while (thisWD.server.isRunning()) { | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |             // Get the game managers | 
            
                                                                        
                            
            
                                    
            
            
                | 43 |  |  |             var gameManager = thisWD.server.getOverworld().getServerLasertagManager(); | 
            
                                                                        
                            
            
                                    
            
            
                | 44 |  |  |             var arenaManager = gameManager.getArenaManager(); | 
            
                                                                        
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 46 |  |  |             // If map is loading, ignore | 
            
                                                                        
                            
            
                                    
            
            
                | 47 |  |  |             if (arenaManager.isLoading()) { | 
            
                                                                        
                            
            
                                    
            
            
                | 48 |  |  |                 this.isIgnoring = true; | 
            
                                                                        
                            
            
                                    
            
            
                | 49 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 51 |  |  |             long lastServerTimeReference = ((DedicatedServerWatchdog) (Object) this).server.getTimeReference(); | 
            
                                                                        
                            
            
                                    
            
            
                | 52 |  |  |             long now = Util.getMeasuringTimeMs(); | 
            
                                                                        
                            
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 55 |  |  |             long difference = now - lastServerTimeReference; | 
            
                                                                        
                            
            
                                    
            
            
                | 56 |  |  |             if (difference > ((DedicatedServerWatchdog) (Object) this).maxTickTime) { | 
            
                                                                        
                            
            
                                    
            
            
                | 57 |  |  |                 if (!this.isIgnoring) { | 
            
                                                                        
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 59 |  |  |                     DedicatedServerWatchdog.LOGGER.error(LogUtils.FATAL_MARKER, "A single server tick took {} seconds (should be max {})", String.format(Locale.ROOT, "%.2f", (float) difference / 1000.0F), String.format(Locale.ROOT, "%.2f", 0.05F)); | 
            
                                                                        
                            
            
                                    
            
            
                | 60 |  |  |                     DedicatedServerWatchdog.LOGGER.error(LogUtils.FATAL_MARKER, "Considering it to be crashed, server will forcibly shutdown."); | 
            
                                                                        
                            
            
                                    
            
            
                | 61 |  |  |                     ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); | 
            
                                                                        
                            
            
                                    
            
            
                | 62 |  |  |                     ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true); | 
            
                                                                        
                            
            
                                    
            
            
                | 63 |  |  |                     StringBuilder stringBuilder = new StringBuilder(); | 
            
                                                                        
                            
            
                                    
            
            
                | 64 |  |  |                     Error error = new Error("Watchdog"); | 
            
                                                                        
                            
            
                                    
            
            
                | 65 |  |  |                     ThreadInfo[] var11 = threadInfos; | 
            
                                                                        
                            
            
                                    
            
            
                | 66 |  |  |                     int var12 = threadInfos.length; | 
            
                                                                        
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 68 |  |  |                     for (int var13 = 0; var13 < var12; ++var13) { | 
            
                                                                        
                            
            
                                    
            
            
                | 69 |  |  |                         ThreadInfo threadInfo = var11[var13]; | 
            
                                                                        
                            
            
                                    
            
            
                | 70 |  |  |                         if (threadInfo.getThreadId() == ((DedicatedServerWatchdog) (Object) this).server.getThread().getId()) { | 
            
                                                                        
                            
            
                                    
            
            
                | 71 |  |  |                             error.setStackTrace(threadInfo.getStackTrace()); | 
            
                                                                        
                            
            
                                    
            
            
                | 72 |  |  |                         } | 
            
                                                                        
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 74 |  |  |                         stringBuilder.append(threadInfo); | 
            
                                                                        
                            
            
                                    
            
            
                | 75 |  |  |                         stringBuilder.append("\n"); | 
            
                                                                        
                            
            
                                    
            
            
                | 76 |  |  |                     } | 
            
                                                                        
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 78 |  |  |                     CrashReport crashReport = new CrashReport("Watching Server", error); | 
            
                                                                        
                            
            
                                    
            
            
                | 79 |  |  |                     ((DedicatedServerWatchdog) (Object) this).server.addSystemDetails(crashReport.getSystemDetailsSection()); | 
            
                                                                        
                            
            
                                    
            
            
                | 80 |  |  |                     CrashReportSection crashReportSection = crashReport.addElement("Thread Dump"); | 
            
                                                                        
                            
            
                                    
            
            
                | 81 |  |  |                     crashReportSection.add("Threads", stringBuilder); | 
            
                                                                        
                            
            
                                    
            
            
                | 82 |  |  |                     CrashReportSection crashReportSection2 = crashReport.addElement("Performance stats"); | 
            
                                                                        
                            
            
                                    
            
            
                | 83 |  |  |                     crashReportSection2.add("Random tick rate", () -> ((DedicatedServerWatchdog) (Object) this).server.getSaveProperties().getGameRules().get(GameRules.RANDOM_TICK_SPEED).toString()); | 
            
                                                                        
                            
            
                                    
            
            
                | 84 |  |  |                     crashReportSection2.add("Level stats", () -> Streams.stream(((DedicatedServerWatchdog) (Object) this).server.getWorlds()).map((serverWorld) -> { | 
            
                                                                        
                            
            
                                    
            
            
                | 85 |  |  |                         RegistryKey var10000 = serverWorld.getRegistryKey(); | 
            
                                                                        
                            
            
                                    
            
            
                | 86 |  |  |                         return "" + var10000 + ": " + serverWorld.getDebugString(); | 
            
                                                                        
                            
            
                                    
            
            
                | 87 |  |  |                     }).collect(Collectors.joining(",\n"))); | 
            
                                                                        
                            
            
                                    
            
            
                | 88 |  |  |                     Bootstrap.println("Crash report:\n" + crashReport.asString()); | 
            
                                                                        
                            
            
                                    
            
            
                | 89 |  |  |                     File file = new File(new File(((DedicatedServerWatchdog) (Object) this).server.getRunDirectory(), "crash-reports"), "crash-" + Util.getFormattedCurrentTime() + "-server.txt"); | 
            
                                                                        
                            
            
                                    
            
            
                | 90 |  |  |                     if (crashReport.writeToFile(file)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 91 |  |  |                         DedicatedServerWatchdog.LOGGER.error("This crash report has been saved to: {}", file.getAbsolutePath()); | 
            
                                                                        
                            
            
                                    
            
            
                | 92 |  |  |                     } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 93 |  |  |                         DedicatedServerWatchdog.LOGGER.error("We were unable to save this crash report to disk."); | 
            
                                                                        
                            
            
                                    
            
            
                | 94 |  |  |                     } | 
            
                                                                        
                            
            
                                    
            
            
                | 95 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 96 |  |  |                     ((DedicatedServerWatchdog) (Object) this).shutdown(); | 
            
                                                                        
                            
            
                                    
            
            
                | 97 |  |  |                 } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 98 |  |  |                     // Only ignore the first time | 
            
                                                                        
                            
            
                                    
            
            
                | 99 |  |  |                     this.isIgnoring = false; | 
            
                                                                        
                            
            
                                    
            
            
                | 100 |  |  |                     LasertagMod.LOGGER.info("Watchdog now not ignoring anymore."); | 
            
                                                                        
                            
            
                                    
            
            
                | 101 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 102 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 104 |  |  |             try { | 
            
                                                                        
                            
            
                                    
            
            
                | 105 |  |  |                 Thread.sleep(((DedicatedServerWatchdog) (Object) this).maxTickTime); | 
            
                                                                        
                            
            
                                    
            
            
                | 106 |  |  |             } catch (InterruptedException ignored) { | 
            
                                                                        
                            
            
                                    
            
            
                | 107 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 108 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 110 |  |  |         ci.cancel(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 112 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 113 |  |  |  |