1717import org .spongepowered .asm .mixin .Mixin ;
1818import org .spongepowered .asm .mixin .Shadow ;
1919import org .spongepowered .asm .mixin .injection .At ;
20+ import org .spongepowered .asm .mixin .injection .Inject ;
21+ import org .spongepowered .asm .mixin .injection .callback .CallbackInfo ;
2022
2123import java .net .Proxy ;
2224import java .util .concurrent .atomic .AtomicBoolean ;
@@ -28,6 +30,7 @@ public abstract class IntegratedServerMixin extends MinecraftServer implements I
2830 @ Shadow
2931 private boolean paused ;
3032
33+ private int mfix$numTickServerCalls = 0 ;
3134 private final AtomicBoolean mfix$hasPrimaryClientJoined = new AtomicBoolean (false );
3235
3336 public IntegratedServerMixin (Thread serverThread , LevelStorageSource .LevelStorageAccess storageSource , PackRepository packRepository , WorldStem worldStem , Proxy proxy , DataFixer fixerUpper , Services services , ChunkProgressListenerFactory progressListenerFactory ) {
@@ -44,14 +47,26 @@ private boolean preventTicks(Minecraft instance, Operation<Boolean> original) {
4447 return !mfix$hasPrimaryClientJoined .get () || original .call (instance );
4548 }
4649
50+ /**
51+ * @author embeddedt
52+ * @reason Keep our own tick count for the integrated server specifically, rather than relying on super
53+ * to increment.
54+ */
55+ @ Inject (method = "tickServer" , at = @ At ("HEAD" ))
56+ private void mfix$countTicks (CallbackInfo ci ) {
57+ this .mfix$numTickServerCalls ++;
58+ }
59+
4760 /**
4861 * @author embeddedt
4962 * @reason If waiting for a client connection to exist, we only need to tick the server connection,
50- * not the whole server as vanilla does.
63+ * not the whole server as vanilla does. However, we must tick the whole server once to accommodate mods
64+ * that rely on the first tick to initialize state as a side effect. Not doing this causes issues like
65+ * <a href="https://github.com/embeddedt/ModernFix/issues/639">#639</a>.
5166 */
5267 @ WrapWithCondition (method = "tickServer" , at = @ At (value = "INVOKE" , target = "Lnet/minecraft/server/MinecraftServer;tickServer(Ljava/util/function/BooleanSupplier;)V" , ordinal = 0 ))
5368 private boolean preventRunningFullServerTick (MinecraftServer server , BooleanSupplier hasTimeLeft ) {
54- if (this .paused && !mfix$hasPrimaryClientJoined .get ()) {
69+ if (this .mfix$numTickServerCalls >= 2 && this . paused && !mfix$hasPrimaryClientJoined .get ()) {
5570 var conn = this .getConnection ();
5671 if (conn != null ) {
5772 conn .tick ();
0 commit comments