diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/MinecraftServerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/MinecraftServerMixin.java new file mode 100644 index 00000000..b85fde40 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/core/MinecraftServerMixin.java @@ -0,0 +1,24 @@ +package org.embeddedt.modernfix.common.mixin.core; + +import net.minecraft.Util; +import net.minecraft.server.MinecraftServer; +import org.embeddedt.modernfix.duck.ITimeTrackingServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftServer.class) +public class MinecraftServerMixin implements ITimeTrackingServer { + private long mfix$lastTickStartTime = -1L; + + @Override + public long mfix$getLastTickStartTime() { + return mfix$lastTickStartTime; + } + + @Inject(method = "runServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;tickServer(Ljava/util/function/BooleanSupplier;)V")) + private void trackTickTime(CallbackInfo ci) { + mfix$lastTickStartTime = Util.getMillis(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/duck/ITimeTrackingServer.java b/common/src/main/java/org/embeddedt/modernfix/duck/ITimeTrackingServer.java new file mode 100644 index 00000000..1b739595 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/duck/ITimeTrackingServer.java @@ -0,0 +1,5 @@ +package org.embeddedt.modernfix.duck; + +public interface ITimeTrackingServer { + long mfix$getLastTickStartTime(); +} diff --git a/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java b/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java index bb7b3bce..0df35e22 100644 --- a/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java +++ b/common/src/main/java/org/embeddedt/modernfix/world/IntegratedWatchdog.java @@ -4,9 +4,11 @@ import com.mojang.logging.LogUtils; import net.minecraft.DefaultUncaughtExceptionHandlerWithName; import net.minecraft.Util; import net.minecraft.server.MinecraftServer; +import org.embeddedt.modernfix.duck.ITimeTrackingServer; import org.slf4j.Logger; import java.lang.ref.WeakReference; +import java.util.OptionalLong; public class IntegratedWatchdog extends Thread { private static final Logger LOGGER = LogUtils.getLogger(); @@ -22,23 +24,27 @@ public class IntegratedWatchdog extends Thread { this.setName("ModernFix integrated server watchdog"); } + private OptionalLong getLastTickStart() { + MinecraftServer server = this.server.get(); + if(server == null || !server.isRunning()) + return OptionalLong.empty(); + return OptionalLong.of(((ITimeTrackingServer)server).mfix$getLastTickStartTime()); + } + public void run() { while(true) { - MinecraftServer server = this.server.get(); - if(server == null || !server.isRunning()) + OptionalLong lastTickStart = getLastTickStart(); + if(!lastTickStart.isPresent()) { return; - long nextTick = server.getNextTickTime(); + } long curTime = Util.getMillis(); - long delta = curTime - nextTick; + long delta = curTime - lastTickStart.getAsLong(); if(delta > MAX_TICK_DELTA) { LOGGER.error("A single server tick has taken {}, more than {} milliseconds", delta, MAX_TICK_DELTA); LOGGER.error(ThreadDumper.obtainThreadDump()); - nextTick = 0; - curTime = 0; } - server = null; /* allow GC */ try { - Thread.sleep(nextTick + MAX_TICK_DELTA - curTime); + Thread.sleep(MAX_TICK_DELTA - delta); } catch(InterruptedException ignored) { } }