From c2f585da9551d925c01b391ddd151e02c5037382 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 14 Apr 2026 22:20:53 -0400 Subject: [PATCH] Fix rare crash from HandshakeHandler in 5.27.0+ The existing Forge logic can concurrently modify sentMessages from two threads, since handleIndexedMessage runs on the Netty thread, while tickServer is on the server thread. Ticking the handler faster made the race condition significantly more likely to manifest. --- .../fix_handshake_stall/HandshakeHandlerMixin.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/fix_handshake_stall/HandshakeHandlerMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/fix_handshake_stall/HandshakeHandlerMixin.java index a3c8f503..ef2b13be 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/fix_handshake_stall/HandshakeHandlerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/fix_handshake_stall/HandshakeHandlerMixin.java @@ -8,8 +8,11 @@ import net.minecraftforge.network.NetworkRegistry; 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.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Collections; import java.util.List; @Mixin(value = HandshakeHandler.class, remap = false) @@ -23,6 +26,16 @@ public class HandshakeHandlerMixin { @Shadow private List sentMessages; + /** + * @author embeddedt + * @reason we must synchronize sentMessages because it is modified from both the Netty thread and the + * server thread + */ + @Inject(method = "", at = @At("RETURN")) + private void synchronizeSentMessages(CallbackInfo ci) { + this.sentMessages = Collections.synchronizedList(this.sentMessages); + } + /** * @author embeddedt * @reason Forge only sends one login payload per tick. It takes many seconds to send all the payloads at this rate.