From 6ecb87e8dde0275d63595f98b7df098f41c45e04 Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Thu, 15 Jun 2017 11:58:50 +0200 Subject: [PATCH] Add workaround for race condition preventing us from joining SP (see MinecraftForge/MinecraftForge#3974) This is done by preventing all calls to ChannelConfig.setAutoRead(false) during the call to FMLNetworkHandler.fmlClientHandshake (the two @Redirects in MixinNetworkDispatcher) and manually issuing the call before handleLoginSuccess returns (at which point the NetHandlerPlayClient has been set). This commit should be reverted once the issue mentioned above has been fixed. --- .../mixin/MixinNetHandlerLoginClient.java | 5 +++++ .../recording/mixin/MixinNetworkDispatcher.java | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerLoginClient.java b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerLoginClient.java index 5cbe64bc..74322b0c 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerLoginClient.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerLoginClient.java @@ -24,4 +24,9 @@ public abstract class MixinNetHandlerLoginClient { public void replayModRecording_initiateRecording(CallbackInfo cb) { ReplayModRecording.instance.initiateRecording(networkManager); } + + @Inject(method = "handleLoginSuccess", at=@At("RETURN")) + public void replayModRecording_raceConditionWorkAround(CallbackInfo cb) { + networkManager.channel().config().setAutoRead(true); + } } diff --git a/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java b/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java index c6e2e4d5..f9f5cda5 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java @@ -1,8 +1,11 @@ package com.replaymod.recording.mixin; import com.replaymod.recording.handler.FMLHandshakeFilter; +import io.netty.channel.ChannelConfig; import io.netty.channel.ChannelPipeline; import io.netty.channel.embedded.EmbeddedChannel; +import net.minecraft.network.EnumConnectionState; +import net.minecraft.network.NetworkManager; import net.minecraftforge.fml.common.network.handshake.FMLHandshakeCodec; import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; import net.minecraftforge.fml.relauncher.Side; @@ -10,6 +13,7 @@ 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(value = NetworkDispatcher.class, remap = false) @@ -43,4 +47,17 @@ public abstract class MixinNetworkDispatcher { "replaymod_filter", new FMLHandshakeFilter()); } } + + @Redirect(method = "clientListenForServerHandshake", at = @At(value = "INVOKE", remap = true, target = + "Lnet/minecraft/network/NetworkManager;setConnectionState(Lnet/minecraft/network/EnumConnectionState;)V")) + public void replayModRecording_raceConditionWorkAround1(NetworkManager self, EnumConnectionState ignored) { } + + @Redirect(method = "insertIntoChannel", at = @At(value = "INVOKE", target = + "Lio/netty/channel/ChannelConfig;setAutoRead(Z)Lio/netty/channel/ChannelConfig;")) + public ChannelConfig replayModRecording_raceConditionWorkAround2(ChannelConfig self, boolean autoRead) { + if (side == Side.CLIENT) { + autoRead = false; + } + return self.setAutoRead(autoRead); + } }