Ensure integrated server is ticked at least once before player connects

Fixes #639
This commit is contained in:
embeddedt 2026-04-12 16:02:54 -04:00
parent d749205427
commit 85955ebf75
No known key found for this signature in database
GPG Key ID: A69433EC199B5613

View File

@ -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
* <a href="https://github.com/embeddedt/ModernFix/issues/639">#639</a>.
*/
@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();