diff --git a/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java b/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java index 0ea736a1..fca4cd6c 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java @@ -1,70 +1 @@ -//#if MC<11400 -//$$ package com.replaymod.recording.mixin; -//$$ -//$$ import com.replaymod.recording.handler.FMLHandshakeFilter; -//$$ import io.netty.channel.ChannelPipeline; -//$$ import io.netty.channel.embedded.EmbeddedChannel; -//$$ import net.minecraftforge.fml.common.network.handshake.FMLHandshakeCodec; -//$$ import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; -//$$ import net.minecraftforge.fml.relauncher.Side; -//$$ 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; -//$$ -//#if MC>=11200 -//$$ import io.netty.channel.ChannelConfig; -//$$ import net.minecraft.network.EnumConnectionState; -//$$ import net.minecraft.network.NetworkManager; -//$$ import org.spongepowered.asm.mixin.injection.Redirect; -//#endif -//$$ -//$$ @Mixin(value = NetworkDispatcher.class, remap = false) -//$$ public abstract class MixinNetworkDispatcher { -//$$ -//$$ @Shadow -//$$ private Side side; -//$$ -//$$ @Shadow -//$$ private EmbeddedChannel handshakeChannel; -//$$ -//$$ /** -//$$ * Always sets fml:isLocal to false on the server side. -//$$ * This effectively removes the difference in the FML handshake between SP and MP -//$$ * and forces the block/item ids, etc. to always be send. -//$$ * Injects a {@link FMLHandshakeFilter} on the client side to filter out -//$$ * those extra, unexpected packets. -//$$ */ -//$$ @Inject(method = "insertIntoChannel", at=@At("HEAD")) -//$$ public void replayModRecording_setupForLocalRecording(CallbackInfo cb) { -//$$ // If we're in multiplayer, everything is fine as is -//$$ if (!handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).get()) return; -//$$ -//$$ if (side == Side.SERVER) { -//$$ // On the server side, force all packets to be sent -//$$ handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).set(false); -//$$ } else { -//$$ // On the client side, discard additional packets -//$$ ChannelPipeline pipeline = handshakeChannel.pipeline(); -//$$ pipeline.addAfter(pipeline.context(FMLHandshakeCodec.class).name(), -//$$ "replaymod_filter", new FMLHandshakeFilter()); -//$$ } -//$$ } -//$$ - //#if MC>=11200 - //$$ @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); - //$$ } - //#endif -//$$ } -//#endif +// 1.12.2 and below diff --git a/versions/1.12.2/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java b/versions/1.12.2/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java new file mode 100644 index 00000000..120dd947 --- /dev/null +++ b/versions/1.12.2/src/main/java/com/replaymod/recording/mixin/MixinNetworkDispatcher.java @@ -0,0 +1,69 @@ +package com.replaymod.recording.mixin; + +import com.replaymod.recording.handler.FMLHandshakeFilter; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.embedded.EmbeddedChannel; +import net.minecraftforge.fml.common.network.handshake.FMLHandshakeCodec; +import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; +import net.minecraftforge.fml.relauncher.Side; +import org.spongepowered.asm.mixin.Final; +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; + +//#if MC>=11200 +import io.netty.channel.ChannelConfig; +import net.minecraft.network.EnumConnectionState; +import net.minecraft.network.NetworkManager; +import org.spongepowered.asm.mixin.injection.Redirect; +//#endif + +@Mixin(value = NetworkDispatcher.class, remap = false) +public abstract class MixinNetworkDispatcher { + + @Final @Shadow + private Side side; + + @Final @Shadow + private EmbeddedChannel handshakeChannel; + + /** + * Always sets fml:isLocal to false on the server side. + * This effectively removes the difference in the FML handshake between SP and MP + * and forces the block/item ids, etc. to always be send. + * Injects a {@link FMLHandshakeFilter} on the client side to filter out + * those extra, unexpected packets. + */ + @Inject(method = "insertIntoChannel", at=@At("HEAD")) + public void replayModRecording_setupForLocalRecording(CallbackInfo cb) { + // If we're in multiplayer, everything is fine as is + if (!handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).get()) return; + + if (side == Side.SERVER) { + // On the server side, force all packets to be sent + handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).set(false); + } else { + // On the client side, discard additional packets + ChannelPipeline pipeline = handshakeChannel.pipeline(); + pipeline.addAfter(pipeline.context(FMLHandshakeCodec.class).name(), + "replaymod_filter", new FMLHandshakeFilter()); + } + } + + //#if MC>=11200 + @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); + } + //#endif +}