Passed
Push — main ( 6d86fc...b981dd )
by Etienne
01:40
created

runOverride(CallbackInfo)   C

Complexity

Conditions 9

Size

Total Lines 70
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 48
c 1
b 0
f 0
dl 0
loc 70
rs 6.3684

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
package de.kleiner3.lasertag.mixin;
2
3
import com.google.common.collect.Streams;
4
import com.mojang.logging.LogUtils;
5
import de.kleiner3.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
        while (((DedicatedServerWatchdog) (Object) this).server.isRunning()) {
39
40
            // If map is loading, ignore
41
            if (((DedicatedServerWatchdog) (Object) this).server.getLasertagServerManager().getMapManager().isLoading()) {
42
                this.isIgnoring = true;
43
            }
44
45
            long lastServerTimeReference = ((DedicatedServerWatchdog) (Object) this).server.getTimeReference();
46
            long now = Util.getMeasuringTimeMs();
47
48
49
            long difference = now - lastServerTimeReference;
50
            if (difference > ((DedicatedServerWatchdog) (Object) this).maxTickTime) {
51
                if (!this.isIgnoring) {
52
53
                    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));
54
                    DedicatedServerWatchdog.LOGGER.error(LogUtils.FATAL_MARKER, "Considering it to be crashed, server will forcibly shutdown.");
55
                    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
56
                    ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
57
                    StringBuilder stringBuilder = new StringBuilder();
58
                    Error error = new Error("Watchdog");
59
                    ThreadInfo[] var11 = threadInfos;
60
                    int var12 = threadInfos.length;
61
62
                    for (int var13 = 0; var13 < var12; ++var13) {
63
                        ThreadInfo threadInfo = var11[var13];
64
                        if (threadInfo.getThreadId() == ((DedicatedServerWatchdog) (Object) this).server.getThread().getId()) {
65
                            error.setStackTrace(threadInfo.getStackTrace());
66
                        }
67
68
                        stringBuilder.append(threadInfo);
69
                        stringBuilder.append("\n");
70
                    }
71
72
                    CrashReport crashReport = new CrashReport("Watching Server", error);
73
                    ((DedicatedServerWatchdog) (Object) this).server.addSystemDetails(crashReport.getSystemDetailsSection());
74
                    CrashReportSection crashReportSection = crashReport.addElement("Thread Dump");
75
                    crashReportSection.add("Threads", stringBuilder);
76
                    CrashReportSection crashReportSection2 = crashReport.addElement("Performance stats");
77
                    crashReportSection2.add("Random tick rate", () -> ((DedicatedServerWatchdog) (Object) this).server.getSaveProperties().getGameRules().get(GameRules.RANDOM_TICK_SPEED).toString());
78
                    crashReportSection2.add("Level stats", () -> Streams.stream(((DedicatedServerWatchdog) (Object) this).server.getWorlds()).map((serverWorld) -> {
79
                        RegistryKey var10000 = serverWorld.getRegistryKey();
80
                        return "" + var10000 + ": " + serverWorld.getDebugString();
81
                    }).collect(Collectors.joining(",\n")));
82
                    Bootstrap.println("Crash report:\n" + crashReport.asString());
83
                    File file = new File(new File(((DedicatedServerWatchdog) (Object) this).server.getRunDirectory(), "crash-reports"), "crash-" + Util.getFormattedCurrentTime() + "-server.txt");
84
                    if (crashReport.writeToFile(file)) {
85
                        DedicatedServerWatchdog.LOGGER.error("This crash report has been saved to: {}", file.getAbsolutePath());
86
                    } else {
87
                        DedicatedServerWatchdog.LOGGER.error("We were unable to save this crash report to disk.");
88
                    }
89
90
                    ((DedicatedServerWatchdog) (Object) this).shutdown();
91
                } else {
92
                    // Only ignore the first time
93
                    this.isIgnoring = false;
94
                    LasertagMod.LOGGER.info("Watchdog now not ignoring anymore.");
95
                }
96
            }
97
98
            try {
99
                Thread.sleep(((DedicatedServerWatchdog) (Object) this).maxTickTime);
100
            } catch (InterruptedException ignored) {
101
            }
102
        }
103
104
        ci.cancel();
105
    }
106
}
107