From 85955ebf75749a96289ad42acdf2a330981df72c Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 12 Apr 2026 16:02:54 -0400 Subject: [PATCH] Ensure integrated server is ticked at least once before player connects Fixes #639 --- .../IntegratedServerMixin.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/suspend_integrated_server_during_load/IntegratedServerMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/suspend_integrated_server_during_load/IntegratedServerMixin.java index 57cd9f8b..a7090b1b 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/suspend_integrated_server_during_load/IntegratedServerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/suspend_integrated_server_during_load/IntegratedServerMixin.java @@ -17,6 +17,8 @@ import org.embeddedt.modernfix.duck.suspend_integrated_server_during_load.IDefer import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.net.Proxy; import java.util.concurrent.atomic.AtomicBoolean; @@ -28,6 +30,7 @@ public abstract class IntegratedServerMixin extends MinecraftServer implements I @Shadow private boolean paused; + private int mfix$numTickServerCalls = 0; private final AtomicBoolean mfix$hasPrimaryClientJoined = new AtomicBoolean(false); public IntegratedServerMixin(Thread serverThread, LevelStorageSource.LevelStorageAccess storageSource, PackRepository packRepository, WorldStem worldStem, Proxy proxy, DataFixer fixerUpper, Services services, ChunkProgressListenerFactory progressListenerFactory) { @@ -44,14 +47,26 @@ public abstract class IntegratedServerMixin extends MinecraftServer implements I return !mfix$hasPrimaryClientJoined.get() || original.call(instance); } + /** + * @author embeddedt + * @reason Keep our own tick count for the integrated server specifically, rather than relying on super + * to increment. + */ + @Inject(method = "tickServer", at = @At("HEAD")) + private void mfix$countTicks(CallbackInfo ci) { + this.mfix$numTickServerCalls++; + } + /** * @author embeddedt * @reason If waiting for a client connection to exist, we only need to tick the server connection, - * not the whole server as vanilla does. + * not the whole server as vanilla does. However, we must tick the whole server once to accommodate mods + * that rely on the first tick to initialize state as a side effect. Not doing this causes issues like + * #639. */ @WrapWithCondition(method = "tickServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;tickServer(Ljava/util/function/BooleanSupplier;)V", ordinal = 0)) private boolean preventRunningFullServerTick(MinecraftServer server, BooleanSupplier hasTimeLeft) { - if (this.paused && !mfix$hasPrimaryClientJoined.get()) { + if (this.mfix$numTickServerCalls >= 2 && this.paused && !mfix$hasPrimaryClientJoined.get()) { var conn = this.getConnection(); if (conn != null) { conn.tick();