Let Minecraft handle packet decoding during playback

We've done this ourselves only because it was easier at the beginning.
However by now (and especially with 1.20.5), Minecraft's packet decoding
has become substantially more sophisticated, to the point that it's
probably a bad idea to try to do it ourselves.

This commit gives back that responsibility to Minecraft by adding the
standard decoder (and encoder because it's required for proper
connection state management on modern versions) to our channel pipeline,
changes the full and the quick replay sender to send raw `ByteBuf`s into
the front of the channel, and moves the posititon of the full replay
sender in the channel pipeline such that it can see and modify packets
after Minecraft has decoded them.
This commit is contained in:
Jonas Herzig
2024-05-12 17:55:07 +02:00
parent ad49a69f37
commit fe0677923c
5 changed files with 50 additions and 138 deletions

View File

@@ -33,7 +33,9 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.network.ClientLoginNetworkHandler;
import net.minecraft.client.util.Window;
import net.minecraft.network.DecoderHandler;
import net.minecraft.network.NetworkState;
import net.minecraft.network.PacketEncoder;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
@@ -46,13 +48,6 @@ import java.util.*;
//$$ import net.minecraft.client.resource.server.ServerResourcePackManager;
//#endif
//#if MC>=12002
//$$ import io.netty.channel.ChannelDuplexHandler;
//$$ import io.netty.channel.ChannelPromise;
//$$ import net.minecraft.network.handler.NetworkStateTransitionHandler;
//$$ import net.minecraft.network.packet.Packet;
//#endif
//#if MC>=12000
//$$ import com.mojang.blaze3d.systems.VertexSorter;
//$$ import net.minecraft.client.gui.DrawContext;
@@ -129,6 +124,8 @@ import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
public class ReplayHandler {
public static final String PACKET_HANDLER_NAME = "ReplayModReplay_packetHandler";
private static MinecraftClient mc = getMinecraft();
/**
@@ -180,7 +177,7 @@ public class ReplayHandler {
markers = replayFile.getMarkers().or(Collections.emptySet());
fullReplaySender = new FullReplaySender(this, replayFile, false);
fullReplaySender = new FullReplaySender(this, replayFile);
//#if MC>=10800
quickReplaySender = new QuickReplaySender(ReplayModReplay.instance, replayFile);
//#endif
@@ -319,17 +316,25 @@ public class ReplayHandler {
//$$ ChannelOutboundHandlerAdapter dummyHandler = new ChannelOutboundHandlerAdapter();
//$$ channel = new EmbeddedChannel(dummyHandler);
//$$ channel.pipeline().remove(dummyHandler);
//$$ channel.pipeline().removeLast();
//#endif
quickReplaySender.setChannel(channel);
fullReplaySender.setChannel(channel);
//#if MC>=12002
//$$ channel.pipeline().addLast("decoder", new DecoderHandler(ClientConnection.CLIENTBOUND_PROTOCOL_KEY));
//$$ channel.pipeline().addLast("encoder", new PacketEncoder(ClientConnection.SERVERBOUND_PROTOCOL_KEY));
//#else
channel.pipeline().addLast("decoder", new DecoderHandler(NetworkSide.CLIENTBOUND));
channel.pipeline().addLast("encoder", new PacketEncoder(NetworkSide.SERVERBOUND));
//#endif
//#if MC>=10800
channel.pipeline().addLast("ReplayModReplay_quickReplaySender", quickReplaySender);
//#endif
channel.pipeline().addLast("ReplayModReplay_replaySender", fullReplaySender);
//#if MC>=12002
//$$ channel.pipeline().addLast("ReplayModReplay_transition", new DummyNetworkStateTransitionHandler());
//$$ channel.pipeline().addLast("bundler", new PacketBundler(ClientConnection.CLIENTBOUND_PROTOCOL_KEY));
//#elseif MC>=11904
//$$ channel.pipeline().addLast("bundler", new PacketBundler(NetworkSide.CLIENTBOUND));
//#endif
channel.pipeline().addLast(PACKET_HANDLER_NAME, quickMode ? quickReplaySender : fullReplaySender);
channel.pipeline().addLast("packet_handler", networkManager);
channel.pipeline().fireChannelActive();
@@ -459,6 +464,8 @@ public class ReplayHandler {
targetCameraPosition = null;
}
channel.pipeline().replace(PACKET_HANDLER_NAME, PACKET_HANDLER_NAME, quickMode ? quickReplaySender : fullReplaySender);
if (quickMode) {
quickReplaySender.register();
quickReplaySender.restart();
@@ -810,24 +817,4 @@ public class ReplayHandler {
//$$ }
//#endif
}
//#if MC>=12002
//$$ private static class DummyNetworkStateTransitionHandler extends ChannelDuplexHandler {
//$$ @Override
//$$ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//$$ if (msg instanceof Packet<?> packet) {
//$$ NetworkStateTransitionHandler.handle(ctx.channel().attr(ClientConnection.CLIENTBOUND_PROTOCOL_KEY), packet);
//$$ }
//$$ super.channelRead(ctx, msg);
//$$ }
//$$
//$$ @Override
//$$ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
//$$ if (msg instanceof Packet<?> packet) {
//$$ NetworkStateTransitionHandler.handle(ctx.channel().attr(ClientConnection.SERVERBOUND_PROTOCOL_KEY), packet);
//$$ }
//$$ super.write(ctx, msg, promise);
//$$ }
//$$ }
//#endif
}