package net.minecraft.server.dedicated;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ServerHangWatchdog implements Runnable
{
private static final Logger LOGGER = LogManager.getLogger();
private final DedicatedServer server;
private final long maxTickTime;
private static final String __OBFID = "CL_00002634";
public ServerHangWatchdog(DedicatedServer server)
{
this.server = server;
this.maxTickTime = server.getMaxTickTime();
}
public void run()
{
while (this.server.isServerRunning())
{
long var1 = this.server.getCurrentTime();
long var3 = MinecraftServer.getCurrentTimeMillis();
long var5 = var3 - var1;
if (var5 > this.maxTickTime)
{
LOGGER.fatal("A single server tick took " + String.format("%.2f", new Object[] {Float.valueOf((float)var5 / 1000.0F)}) + " seconds (should be max " + String.format("%.2f", new Object[] {Float.valueOf(0.05F)}) + ")");
LOGGER.fatal("Considering it to be crashed, server will forcibly shutdown.");
ThreadMXBean var7 = ManagementFactory.getThreadMXBean();
ThreadInfo[] var8 = var7.dumpAllThreads(true, true);
StringBuilder var9 = new StringBuilder();
Error var10 = new Error();
ThreadInfo[] var11 = var8;
int var12 = var8.length;
for (int var13 = 0; var13 < var12; ++var13)
{
ThreadInfo var14 = var11[var13];
if (var14.getThreadId() == this.server.getServerThread().getId())
{
var10.setStackTrace(var14.getStackTrace());
}
var9.append(var14);
var9.append("\n");
}
CrashReport var16 = new CrashReport("Watching Server", var10);
this.server.addServerInfoToCrashReport(var16);
CrashReportCategory var17 = var16.makeCategory("Thread Dump");
var17.addCrashSection("Threads", var9);
File var18 = new File(new File(this.server.getDataDirectory(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
if (var16.saveToFile(var18))
{
LOGGER.error("This crash report has been saved to: " + var18.getAbsolutePath());
}
else
{
LOGGER.error("We were unable to save this crash report to disk.");
}
this.func_180248_a();
}
try
{
Thread.sleep(var1 + this.maxTickTime - var3);
}
catch (InterruptedException var15)
{
;
}
}
}
private void func_180248_a()
{
try
{
Timer var1 = new Timer();
var1.schedule(new TimerTask()
{
private static final String __OBFID = "CL_00002633";
public void run()
{
Runtime.getRuntime().halt(1);
}
}, 10000L);
System.exit(1);
}
catch (Throwable var2)
{
Runtime.getRuntime().halt(1);
}
}
}