diff --git a/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketDecoder.java b/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketDecoder.java index ecd14e030..1ea67a936 100644 --- a/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketDecoder.java +++ b/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketDecoder.java @@ -18,26 +18,21 @@ package io.github.retrooper.packetevents.handler; -import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.List; -@ChannelHandler.Sharable +@ApiStatus.Internal public class PacketDecoder extends MessageToMessageDecoder { - private static Method DECOMPRESSOR_METHOD, COMPRESSOR_METHOD; + public User user; public Player player; - public boolean checkedCompression; public PacketDecoder(User user) { this.user = user; @@ -45,75 +40,13 @@ public PacketDecoder(User user) { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { - if (msg.isReadable()) { - ByteBuf outputBuffer = ctx.alloc().buffer().writeBytes(msg); - boolean recompress = handleCompression(ctx, outputBuffer); - PacketEventsImplHelper.handleClientBoundPacket(ctx.channel(), user, player, outputBuffer, false); - if (outputBuffer.isReadable()) { - if (recompress) { - recompress(ctx, outputBuffer); - } - out.add(outputBuffer.retain()); - } + if (!msg.isReadable()) { + return; } - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - super.channelInactive(ctx); - } - - - private boolean handleCompression(ChannelHandlerContext ctx, ByteBuf buffer) { - if (checkedCompression) return false; - if (ctx.pipeline().names().indexOf("decompress") > ctx.pipeline().names().indexOf(PacketEvents.DECODER_NAME)) { - // Need to decompress this packet due to bad order - ChannelHandler decompressor = ctx.pipeline().get("decompress"); - //CompressionDecoder - try { - if (DECOMPRESSOR_METHOD == null) { - DECOMPRESSOR_METHOD = decompressor.getClass().getDeclaredMethod("decode", ChannelHandlerContext.class, ByteBuf.class, List.class); - } - List list = new ArrayList<>(1); - DECOMPRESSOR_METHOD.invoke(decompressor, ctx, buffer, list); - ByteBuf decompressed = (ByteBuf) list.get(0); - if (buffer != decompressed) { - try { - buffer.clear().writeBytes(decompressed); - } finally { - decompressed.release(); - } - } - //Relocate handlers - PacketDecoder decoder = (PacketDecoder) ctx.pipeline().remove(PacketEvents.DECODER_NAME); - ctx.pipeline().addAfter("decompress", PacketEvents.DECODER_NAME, decoder); - PacketEncoder encoder = (PacketEncoder) ctx.pipeline().remove(PacketEvents.ENCODER_NAME); - ctx.pipeline().addAfter("compress", PacketEvents.ENCODER_NAME, encoder); - checkedCompression = true; - return true; - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { - e.printStackTrace(); - } - } - return false; - } - - private void recompress(ChannelHandlerContext ctx, ByteBuf buffer) { - ByteBuf compressed = ctx.alloc().buffer(); - try { - ChannelHandler compressor = ctx.pipeline().get("compress"); - if (COMPRESSOR_METHOD == null) { - COMPRESSOR_METHOD = compressor.getClass().getDeclaredMethod("encode", ChannelHandlerContext.class, ByteBuf.class, ByteBuf.class); - } - COMPRESSOR_METHOD.invoke(compressor, ctx, buffer, compressed); - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { - e.printStackTrace(); - } - try { - buffer.clear().writeBytes(compressed); - PacketEvents.getAPI().getLogManager().debug("Recompressed packet!"); - } finally { - compressed.release(); + PacketEventsImplHelper.handleClientBoundPacket(ctx.channel(), this.user, this.player, + msg, false); + if (msg.isReadable()) { + out.add(msg.retain()); } } } diff --git a/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketEncoder.java b/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketEncoder.java index a1833705b..5ac7ccc32 100644 --- a/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketEncoder.java +++ b/fabric/src/main/java/io/github/retrooper/packetevents/handler/PacketEncoder.java @@ -21,16 +21,15 @@ import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; -import io.netty.handler.codec.EncoderException; -import io.netty.handler.codec.MessageToByteEncoder; -import io.netty.util.ReferenceCountUtil; import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class PacketEncoder extends ChannelOutboundHandlerAdapter { -@ChannelHandler.Sharable -public class PacketEncoder extends MessageToByteEncoder { public User user; public Player player; @@ -40,43 +39,26 @@ public PacketEncoder(User user) { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - ByteBuf buf = null; + if (!(msg instanceof ByteBuf in)) { + ctx.write(msg, promise); + return; + } + if (!in.isReadable()) { + in.release(); + return; + } + + ByteBuf out; try { - if (acceptOutboundMessage(msg)) { - ByteBuf in = (ByteBuf) msg; - buf = allocateBuffer(ctx, in, true); - try { - encode(ctx, in, buf); - } finally { - ReferenceCountUtil.release(in); - } - if (buf.isReadable()) { - ctx.write(buf, promise); - } else { - buf.release(); - //We cancelled this packet, do not pass it on to the next handler. - //ctx.write(Unpooled.EMPTY_BUFFER, promise); - } - buf = null; - } else { - ctx.write(msg, promise); - } - } catch (EncoderException e) { - throw e; - } catch (Throwable e) { - throw new EncoderException(e); + out = (ByteBuf) PacketEventsImplHelper.handleServerBoundPacket(ctx.channel(), + this.user, this.player, in, false); } finally { - if (buf != null) { - buf.release(); - } + in.release(); } - } - - @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { - if (msg.isReadable()) { - ByteBuf buffer = (ByteBuf) PacketEventsImplHelper.handleServerBoundPacket(ctx.channel(), user, player, msg, false); - out.writeBytes(buffer.retain()); + if (out.isReadable()) { + ctx.write(out, promise); + } else { + out.release(); } } } diff --git a/fabric/src/main/java/io/github/retrooper/packetevents/mixin/PacketEventsInjectorMixin.java b/fabric/src/main/java/io/github/retrooper/packetevents/mixin/ConnectionMixin.java similarity index 78% rename from fabric/src/main/java/io/github/retrooper/packetevents/mixin/PacketEventsInjectorMixin.java rename to fabric/src/main/java/io/github/retrooper/packetevents/mixin/ConnectionMixin.java index b4358ef19..0d915c74f 100644 --- a/fabric/src/main/java/io/github/retrooper/packetevents/mixin/PacketEventsInjectorMixin.java +++ b/fabric/src/main/java/io/github/retrooper/packetevents/mixin/ConnectionMixin.java @@ -31,21 +31,33 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; +import net.minecraft.SharedConstants; import net.minecraft.network.BandwidthDebugMonitor; import net.minecraft.network.protocol.PacketFlow; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(net.minecraft.network.Connection.class) -public class PacketEventsInjectorMixin { +public class ConnectionMixin { + + // doesn't account for mods like ViaFabric + @Unique + private static final ClientVersion CLIENT_VERSION = + ClientVersion.getById(SharedConstants.getProtocolVersion()); + @Inject(method = "configureSerialization", at = @At("TAIL")) - private static void configureSerialization(ChannelPipeline pipeline, PacketFlow flow, boolean memoryOnly, BandwidthDebugMonitor bandwithDebugMonitor, CallbackInfo ci) throws Exception { + private static void configureSerialization( + ChannelPipeline pipeline, PacketFlow flow, boolean memoryOnly, + BandwidthDebugMonitor bandwithDebugMonitor, CallbackInfo ci + ) { PacketEvents.getAPI().getLogManager().debug("Game connected!"); + Channel channel = pipeline.channel(); - User user = new User(channel, ConnectionState.HANDSHAKING, ClientVersion.getLatest(), - new UserProfile(null, null)); + User user = new User(channel, ConnectionState.HANDSHAKING, + CLIENT_VERSION, new UserProfile(null, null)); ProtocolManager.USERS.put(channel, user); UserConnectEvent connectEvent = new UserConnectEvent(user); @@ -54,10 +66,10 @@ private static void configureSerialization(ChannelPipeline pipeline, PacketFlow channel.unsafe().closeForcibly(); return; } - PacketDecoder decoder = new PacketDecoder(user); - PacketEncoder encoder = new PacketEncoder(user); - channel.pipeline().addAfter("splitter", PacketEvents.DECODER_NAME, decoder); - channel.pipeline().addAfter("prepender", PacketEvents.ENCODER_NAME, encoder); - channel.closeFuture().addListener((ChannelFutureListener) future -> PacketEventsImplHelper.handleDisconnection(user.getChannel(), user.getUUID())); + + channel.pipeline().addAfter("splitter", PacketEvents.DECODER_NAME, new PacketDecoder(user)); + channel.pipeline().addAfter("prepender", PacketEvents.ENCODER_NAME, new PacketEncoder(user)); + channel.closeFuture().addListener((ChannelFutureListener) future -> + PacketEventsImplHelper.handleDisconnection(user.getChannel(), user.getUUID())); } } diff --git a/fabric/src/main/resources/packetevents.mixins.json b/fabric/src/main/resources/packetevents.mixins.json index 27025b073..746a7c528 100644 --- a/fabric/src/main/resources/packetevents.mixins.json +++ b/fabric/src/main/resources/packetevents.mixins.json @@ -4,7 +4,7 @@ "package": "io.github.retrooper.packetevents.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "PacketEventsInjectorMixin" + "ConnectionMixin" ], "client": [ ],