From 70ef892d0f7628fae09510fa2a8dc5631ab9fe89 Mon Sep 17 00:00:00 2001 From: Felipe Paschoal Bergamo <64669985+felipepasc@users.noreply.github.com> Date: Tue, 8 Apr 2025 23:47:02 -0300 Subject: [PATCH 1/5] feat: metadata in packet wrapper system --- .../netty/buffer/ByteBufHelper.java | 5 + .../netty/buffer/ByteBufOperator.java | 2 + .../util/meta/PacketWrapperMeta.java | 32 + .../util/meta/PacketWrapperMetaCache.java | 52 + .../packetevents/wrapper/PacketWrapper.java | 75 +- .../packetevents/handler/PacketDecoder.java | 8 + .../packetevents/handler/PacketEncoder.java | 6 + .../netty/buffer/ByteBufOperatorImpl.java | 7 + .../netty/bytebuf/WrappedIdentifyByteBuf.java | 951 ++++++++++++++++++ .../handlers/PacketEventsDecoder.java | 7 + .../handlers/PacketEventsEncoder.java | 7 + .../buffer/ByteBufOperatorModernImpl.java | 95 +- .../handlers/PacketEventsDecoder.java | 7 + .../handlers/PacketEventsEncoder.java | 7 + .../buffer/ByteBufOperatorModernImpl.java | 7 + 15 files changed, 1200 insertions(+), 68 deletions(-) create mode 100644 api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java create mode 100644 api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java create mode 100644 netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java diff --git a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java index 581c364ba..33aa1f754 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java @@ -23,6 +23,11 @@ import java.nio.charset.Charset; public class ByteBufHelper { + + public static Object create(Object buffer) { + return PacketEvents.getAPI().getNettyManager().getByteBufOperator().create(buffer); + } + public static int capacity(Object buffer) { return PacketEvents.getAPI().getNettyManager().getByteBufOperator().capacity(buffer); } diff --git a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java index 4b20c3f83..de2250dc5 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java +++ b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java @@ -21,6 +21,8 @@ import java.nio.charset.Charset; public interface ByteBufOperator { + Object create(Object original); + int capacity(Object buffer); Object capacity(Object buffer, int capacity); int readerIndex(Object buffer); diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java new file mode 100644 index 000000000..9a7a45319 --- /dev/null +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java @@ -0,0 +1,32 @@ +package com.github.retrooper.packetevents.util.meta; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public class PacketWrapperMeta { + private final Map data = new HashMap<>(); + private final long timestamp = System.currentTimeMillis(); + + public void put(@NotNull String key, @NotNull Object value) { + this.data.put(key, value); + } + + public @Nullable Object getMeta(@NotNull String key) { + return this.data.get(key); + } + + public @NotNull Map get() { + return this.data; + } + + public long getTimestamp() { + return this.timestamp; + } + + public boolean isExpired() { + return getTimestamp() < System.currentTimeMillis(); + } +} diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java new file mode 100644 index 000000000..bc9a7ce28 --- /dev/null +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java @@ -0,0 +1,52 @@ +package com.github.retrooper.packetevents.util.meta; + +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.*; + +public class PacketWrapperMetaCache { + private static final Map META_CACHE = new ConcurrentHashMap<>(); + + public static void setMeta(@NotNull Object buffer, @NotNull String key, @NotNull Object value) { + META_CACHE.computeIfAbsent(buffer, __ -> new PacketWrapperMeta()).put(key, value); + } + + public static @NotNull Map getMeta(@NotNull Object buffer) { + return META_CACHE.computeIfAbsent(buffer, __ -> new PacketWrapperMeta()).get(); + } + + public static void clean() { + Set toRemoveKeys = new HashSet<>(); + + META_CACHE.forEach((o, packetWrapperMeta) -> { + if (packetWrapperMeta.isExpired()) { + toRemoveKeys.add(o); + } + }); + + toRemoveKeys.forEach(META_CACHE::remove); + } + + static { + ThreadFactory threadFactory = new ThreadFactory() { + private int counter = 0; + + @Override + public @NotNull Thread newThread(@NotNull Runnable runnable) { + Thread thread = new Thread(runnable); + + thread.setName("packet-events - meta clean #" + counter++); + thread.setDaemon(false); + + return thread; + } + + }; + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(threadFactory); + scheduledExecutorService.scheduleAtFixedRate(PacketWrapperMetaCache::clean, 0, 10, TimeUnit.SECONDS); + } +} diff --git a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java index 744a56c75..3ea60fb17 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java @@ -51,15 +51,8 @@ import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper; import com.github.retrooper.packetevents.netty.channel.ChannelHelper; import com.github.retrooper.packetevents.protocol.PacketSide; -import com.github.retrooper.packetevents.protocol.chat.ChatType; -import com.github.retrooper.packetevents.protocol.chat.ChatTypes; -import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages; -import com.github.retrooper.packetevents.protocol.chat.MessageSignature; -import com.github.retrooper.packetevents.protocol.chat.Node; -import com.github.retrooper.packetevents.protocol.chat.Parsers; +import com.github.retrooper.packetevents.protocol.chat.*; import com.github.retrooper.packetevents.protocol.chat.Parsers.Parser; -import com.github.retrooper.packetevents.protocol.chat.RemoteChatSession; -import com.github.retrooper.packetevents.protocol.chat.SignedCommandArgument; import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask; import com.github.retrooper.packetevents.protocol.chat.filter.FilterMaskType; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; @@ -89,11 +82,7 @@ import com.github.retrooper.packetevents.protocol.world.Dimension; import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition; import com.github.retrooper.packetevents.resources.ResourceLocation; -import com.github.retrooper.packetevents.util.Either; -import com.github.retrooper.packetevents.util.KnownPack; -import com.github.retrooper.packetevents.util.MathUtil; -import com.github.retrooper.packetevents.util.StringUtil; -import com.github.retrooper.packetevents.util.Vector3i; +import com.github.retrooper.packetevents.util.*; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; import com.github.retrooper.packetevents.util.crypto.MinecraftEncryptionUtil; import com.github.retrooper.packetevents.util.crypto.SaltSignature; @@ -101,6 +90,7 @@ import com.github.retrooper.packetevents.util.mappings.GlobalRegistryHolder; import com.github.retrooper.packetevents.util.mappings.IRegistry; import com.github.retrooper.packetevents.util.mappings.IRegistryHolder; +import com.github.retrooper.packetevents.util.meta.PacketWrapperMetaCache; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.Style; import org.jetbrains.annotations.ApiStatus; @@ -112,31 +102,28 @@ import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.IntFunction; public class PacketWrapper> { + @Nullable public Object buffer; @ApiStatus.Internal public final Object bufferLock = new Object(); + // For use metadata packet system + private final Map metadata = new HashMap<>(); + protected ClientVersion clientVersion; protected ServerVersion serverVersion; - private PacketTypeData packetTypeData; + + private final PacketTypeData packetTypeData; + // For sending chunk data packets, which need this data @Nullable protected User user; @@ -236,6 +223,12 @@ public final void prepareForSend(Object channel, boolean outgoing, boolean proxy buffer = ChannelHelper.pooledByteBuf(channel); } + // Rewrite buffer to a meta-system + this.buffer = ByteBufHelper.create(this.buffer); + + // Wrapped meta system + writeMeta(); + //On proxies, we must rewrite the packet ID in a format compatible for the targeted client version if (proxy) { User user = PacketEvents.getAPI().getProtocolManager().getUser(channel); @@ -251,6 +244,7 @@ public final void prepareForSend(Object channel, boolean outgoing, boolean proxy } else { writeVarInt(packetTypeData.getNativePacketId()); } + write(); } @@ -259,6 +253,34 @@ public final void prepareForSend(Object channel, boolean outgoing) { prepareForSend(channel, outgoing, PacketEvents.getAPI().getInjector().isProxy()); } + public void setMeta(@NotNull String key, @NotNull Object value) { + this.metadata.put(key, value); + } + + public Object getMeta(@NotNull String key) { + return this.metadata.get(key); + } + + public boolean hasMeta(@NotNull String key) { + return this.metadata.containsKey(key); + } + + public @NotNull Map getMetadata() { + return this.metadata; + } + + public void readMeta() { + if (this.buffer != null) { + this.metadata.putAll(PacketWrapperMetaCache.getMeta(this.buffer)); + } + } + + public void writeMeta() { + if (this.buffer != null) { + this.metadata.forEach((s, o) -> PacketWrapperMetaCache.setMeta(this.buffer, s, o)); + } + } + public void read() { } @@ -275,12 +297,17 @@ public void copy(T wrapper) { //Current idea change server version, but still think more public final void readEvent(ProtocolPacketEvent event) { + + // Wrapped meta system + readMeta(); + PacketWrapper last = event.getLastUsedWrapper(); if (last != null) { copy((T) last); } else { read(); } + event.setLastUsedWrapper(this); } 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 4788e6bf4..b8dd25226 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 @@ -21,6 +21,7 @@ import com.github.retrooper.packetevents.protocol.PacketSide; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; @@ -46,8 +47,15 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) if (!msg.isReadable()) { return; } + + // Wrapped meta system + if (!(msg instanceof WrappedIdentifyByteBuf)) { + msg = new WrappedIdentifyByteBuf(msg); + } + PacketEventsImplHelper.handlePacket(ctx.channel(), this.user, this.player, msg, false, this.side); + 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 eded37b8e..6a54d965f 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,6 +21,7 @@ import com.github.retrooper.packetevents.protocol.PacketSide; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; @@ -51,6 +52,11 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) return; } + // Wrapped meta system + if (!(in instanceof WrappedIdentifyByteBuf)) { + in = new WrappedIdentifyByteBuf(in); + } + PacketEventsImplHelper.handlePacket(ctx.channel(), this.user, this.player, in, false, this.side); if (in.isReadable()) { diff --git a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java index af4180e39..262de1d6f 100644 --- a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java +++ b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java @@ -19,11 +19,18 @@ package io.github.retrooper.packetevents.impl.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorImpl implements ByteBufOperator { + + @Override + public Object create(Object original) { + return new WrappedIdentifyByteBuf((ByteBuf) original); + } + @Override public int capacity(Object buffer) { return ((ByteBuf)buffer).capacity(); diff --git a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java new file mode 100644 index 000000000..d9febc936 --- /dev/null +++ b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java @@ -0,0 +1,951 @@ +package io.github.retrooper.packetevents.impl.netty.bytebuf; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.util.ByteProcessor; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.Objects; +import java.util.UUID; + +public class WrappedIdentifyByteBuf extends ByteBuf { + private final UUID identifier; + private final ByteBuf original; + + public WrappedIdentifyByteBuf(ByteBuf original) { + this.identifier = UUID.randomUUID(); + this.original = original; + } + + @Override + public int capacity() { + return original.capacity(); + } + + @Override + public ByteBuf capacity(int newCapacity) { + return original.capacity(newCapacity); + } + + @Override + public int maxCapacity() { + return original.maxCapacity(); + } + + @Override + public ByteBufAllocator alloc() { + return original.alloc(); + } + + @Deprecated + @Override + public ByteOrder order() { + return original.order(); + } + + @Deprecated + @Override + public ByteBuf order(ByteOrder endianness) { + return original.order(endianness); + } + + @Override + public ByteBuf unwrap() { + return original.unwrap(); + } + + @Override + public boolean isDirect() { + return original.isDirect(); + } + + @Override + public boolean isReadOnly() { + return original.isReadOnly(); + } + + @Override + public ByteBuf asReadOnly() { + return original.asReadOnly(); + } + + @Override + public int readerIndex() { + return original.readerIndex(); + } + + @Override + public ByteBuf readerIndex(int readerIndex) { + return original.readerIndex(readerIndex); + } + + @Override + public int writerIndex() { + return original.writerIndex(); + } + + @Override + public ByteBuf writerIndex(int writerIndex) { + return original.writerIndex(writerIndex); + } + + @Override + public ByteBuf setIndex(int readerIndex, int writerIndex) { + return original.setIndex(readerIndex, writerIndex); + } + + @Override + public int readableBytes() { + return original.readableBytes(); + } + + @Override + public int writableBytes() { + return original.writableBytes(); + } + + @Override + public int maxWritableBytes() { + return original.maxWritableBytes(); + } + + @Override + public boolean isReadable() { + return original.isReadable(); + } + + @Override + public boolean isReadable(int numBytes) { + return original.isReadable(numBytes); + } + + @Override + public boolean isWritable() { + return original.isWritable(); + } + + @Override + public boolean isWritable(int numBytes) { + return original.isWritable(numBytes); + } + + @Override + public ByteBuf clear() { + return original.clear(); + } + + @Override + public ByteBuf markReaderIndex() { + return original.markReaderIndex(); + } + + @Override + public ByteBuf resetReaderIndex() { + return original.resetReaderIndex(); + } + + @Override + public ByteBuf markWriterIndex() { + return original.markWriterIndex(); + } + + @Override + public ByteBuf resetWriterIndex() { + return original.resetWriterIndex(); + } + + @Override + public ByteBuf discardReadBytes() { + return original.discardReadBytes(); + } + + @Override + public ByteBuf discardSomeReadBytes() { + return original.discardSomeReadBytes(); + } + + @Override + public ByteBuf ensureWritable(int minWritableBytes) { + return original.ensureWritable(minWritableBytes); + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + return original.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) { + return original.getBoolean(index); + } + + @Override + public byte getByte(int index) { + return original.getByte(index); + } + + @Override + public short getUnsignedByte(int index) { + return original.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + return original.getShort(index); + } + + @Override + public short getShortLE(int index) { + return original.getShortLE(index); + } + + @Override + public int getUnsignedShort(int index) { + return original.getUnsignedShort(index); + } + + @Override + public int getUnsignedShortLE(int index) { + return original.getUnsignedShortLE(index); + } + + @Override + public int getMedium(int index) { + return original.getMedium(index); + } + + @Override + public int getMediumLE(int index) { + return original.getMediumLE(index); + } + + @Override + public int getUnsignedMedium(int index) { + return original.getUnsignedMedium(index); + } + + @Override + public int getUnsignedMediumLE(int index) { + return original.getUnsignedMediumLE(index); + } + + @Override + public int getInt(int index) { + return original.getInt(index); + } + + @Override + public int getIntLE(int index) { + return original.getIntLE(index); + } + + @Override + public long getUnsignedInt(int index) { + return original.getUnsignedInt(index); + } + + @Override + public long getUnsignedIntLE(int index) { + return original.getUnsignedIntLE(index); + } + + @Override + public long getLong(int index) { + return original.getLong(index); + } + + @Override + public long getLongLE(int index) { + return original.getLongLE(index); + } + + @Override + public char getChar(int index) { + return original.getChar(index); + } + + @Override + public float getFloat(int index) { + return original.getFloat(index); + } + + @Override + public double getDouble(int index) { + return original.getDouble(index); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst) { + return original.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex) { + return original.getBytes(index, dst, dstIndex); + } + + @Override + public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + return original.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst) { + return original.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + return original.getBytes(index, dst, dstIndex, length); + } + + @Override + public ByteBuf getBytes(int index, ByteBuffer dst) { + return original.getBytes(index, dst); + } + + @Override + public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + return original.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return original.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, FileChannel out, long position, int length) throws IOException { + return original.getBytes(index, out, position, length); + } + + @Override + public CharSequence getCharSequence(int index, int length, Charset charset) { + return original.getCharSequence(index, length, charset); + } + + @Override + public ByteBuf setBoolean(int index, boolean value) { + return original.setBoolean(index, value); + } + + @Override + public ByteBuf setByte(int index, int value) { + return original.setByte(index, value); + } + + @Override + public ByteBuf setShort(int index, int value) { + return original.setShort(index, value); + } + + @Override + public ByteBuf setShortLE(int index, int value) { + return original.setShortLE(index, value); + } + + @Override + public ByteBuf setMedium(int index, int value) { + return original.setMedium(index, value); + } + + @Override + public ByteBuf setMediumLE(int index, int value) { + return original.setMediumLE(index, value); + } + + @Override + public ByteBuf setInt(int index, int value) { + return original.setInt(index, value); + } + + @Override + public ByteBuf setIntLE(int index, int value) { + return original.setIntLE(index, value); + } + + @Override + public ByteBuf setLong(int index, long value) { + return original.setLong(index, value); + } + + @Override + public ByteBuf setLongLE(int index, long value) { + return original.setLongLE(index, value); + } + + @Override + public ByteBuf setChar(int index, int value) { + return original.setChar(index, value); + } + + @Override + public ByteBuf setFloat(int index, float value) { + return original.setFloat(index, value); + } + + @Override + public ByteBuf setDouble(int index, double value) { + return original.setDouble(index, value); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src) { + return original.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex) { + return original.setBytes(index, src, srcIndex); + } + + @Override + public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + return original.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, byte[] src) { + return original.setBytes(index, src); + } + + @Override + public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + return original.setBytes(index, src, srcIndex, length); + } + + @Override + public ByteBuf setBytes(int index, ByteBuffer src) { + return original.setBytes(index, src); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + return original.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + return original.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, FileChannel in, long position, int length) throws IOException { + return original.setBytes(index, in, position, length); + } + + @Override + public ByteBuf setZero(int index, int length) { + return original.setZero(index, length); + } + + @Override + public int setCharSequence(int index, CharSequence sequence, Charset charset) { + return original.setCharSequence(index, sequence, charset); + } + + @Override + public boolean readBoolean() { + return original.readBoolean(); + } + + @Override + public byte readByte() { + return original.readByte(); + } + + @Override + public short readUnsignedByte() { + return original.readUnsignedByte(); + } + + @Override + public short readShort() { + return original.readShort(); + } + + @Override + public short readShortLE() { + return original.readShortLE(); + } + + @Override + public int readUnsignedShort() { + return original.readUnsignedShort(); + } + + @Override + public int readUnsignedShortLE() { + return original.readUnsignedShortLE(); + } + + @Override + public int readMedium() { + return original.readMedium(); + } + + @Override + public int readMediumLE() { + return original.readMediumLE(); + } + + @Override + public int readUnsignedMedium() { + return original.readUnsignedMedium(); + } + + @Override + public int readUnsignedMediumLE() { + return original.readUnsignedMediumLE(); + } + + @Override + public int readInt() { + return original.readInt(); + } + + @Override + public int readIntLE() { + return original.readIntLE(); + } + + @Override + public long readUnsignedInt() { + return original.readUnsignedInt(); + } + + @Override + public long readUnsignedIntLE() { + return original.readUnsignedIntLE(); + } + + @Override + public long readLong() { + return original.readLong(); + } + + @Override + public long readLongLE() { + return original.readLongLE(); + } + + @Override + public char readChar() { + return original.readChar(); + } + + @Override + public float readFloat() { + return original.readFloat(); + } + + @Override + public double readDouble() { + return original.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) { + return original.readBytes(length); + } + + @Override + public ByteBuf readSlice(int length) { + return original.readSlice(length); + } + + @Override + public ByteBuf readRetainedSlice(int length) { + return original.readRetainedSlice(length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst) { + return original.readBytes(dst); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int length) { + return original.readBytes(dst, length); + } + + @Override + public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + return original.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(byte[] dst) { + return original.readBytes(dst); + } + + @Override + public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { + return original.readBytes(dst, dstIndex, length); + } + + @Override + public ByteBuf readBytes(ByteBuffer dst) { + return original.readBytes(dst); + } + + @Override + public ByteBuf readBytes(OutputStream out, int length) throws IOException { + return original.readBytes(out, length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + return original.readBytes(out, length); + } + + @Override + public CharSequence readCharSequence(int length, Charset charset) { + return original.readCharSequence(length, charset); + } + + @Override + public int readBytes(FileChannel out, long position, int length) throws IOException { + return original.readBytes(out, position, length); + } + + @Override + public ByteBuf skipBytes(int length) { + return original.skipBytes(length); + } + + @Override + public ByteBuf writeBoolean(boolean value) { + return original.writeBoolean(value); + } + + @Override + public ByteBuf writeByte(int value) { + return original.writeByte(value); + } + + @Override + public ByteBuf writeShort(int value) { + return original.writeShort(value); + } + + @Override + public ByteBuf writeShortLE(int value) { + return original.writeShortLE(value); + } + + @Override + public ByteBuf writeMedium(int value) { + return original.writeMedium(value); + } + + @Override + public ByteBuf writeMediumLE(int value) { + return original.writeMediumLE(value); + } + + @Override + public ByteBuf writeInt(int value) { + return original.writeInt(value); + } + + @Override + public ByteBuf writeIntLE(int value) { + return original.writeIntLE(value); + } + + @Override + public ByteBuf writeLong(long value) { + return original.writeLong(value); + } + + @Override + public ByteBuf writeLongLE(long value) { + return original.writeLongLE(value); + } + + @Override + public ByteBuf writeChar(int value) { + return original.writeChar(value); + } + + @Override + public ByteBuf writeFloat(float value) { + return original.writeFloat(value); + } + + @Override + public ByteBuf writeDouble(double value) { + return original.writeDouble(value); + } + + @Override + public ByteBuf writeBytes(ByteBuf src) { + return original.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int length) { + return original.writeBytes(src, length); + } + + @Override + public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + return original.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(byte[] src) { + return original.writeBytes(src); + } + + @Override + public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { + return original.writeBytes(src, srcIndex, length); + } + + @Override + public ByteBuf writeBytes(ByteBuffer src) { + return original.writeBytes(src); + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + return original.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + return original.writeBytes(in, length); + } + + @Override + public int writeBytes(FileChannel in, long position, int length) throws IOException { + return original.writeBytes(in, position, length); + } + + @Override + public ByteBuf writeZero(int length) { + return original.writeZero(length); + } + + @Override + public int writeCharSequence(CharSequence sequence, Charset charset) { + return original.writeCharSequence(sequence, charset); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + return original.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + return original.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + return original.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + return original.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteProcessor processor) { + return original.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteProcessor processor) { + return original.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteProcessor processor) { + return original.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteProcessor processor) { + return original.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() { + return original.copy(); + } + + @Override + public ByteBuf copy(int index, int length) { + return original.copy(index, length); + } + + @Override + public ByteBuf slice() { + return original.slice(); + } + + @Override + public ByteBuf retainedSlice() { + return original.retainedSlice(); + } + + @Override + public ByteBuf slice(int index, int length) { + return original.slice(index, length); + } + + @Override + public ByteBuf retainedSlice(int index, int length) { + return original.retainedSlice(index, length); + } + + @Override + public ByteBuf duplicate() { + return original.duplicate(); + } + + @Override + public ByteBuf retainedDuplicate() { + return original.retainedDuplicate(); + } + + @Override + public int nioBufferCount() { + return original.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() { + return original.nioBuffer(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return original.nioBuffer(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return original.internalNioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() { + return original.nioBuffers(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return original.nioBuffers(index, length); + } + + @Override + public boolean hasArray() { + return original.hasArray(); + } + + @Override + public byte[] array() { + return original.array(); + } + + @Override + public int arrayOffset() { + return original.arrayOffset(); + } + + @Override + public boolean hasMemoryAddress() { + return original.hasMemoryAddress(); + } + + @Override + public long memoryAddress() { + return original.memoryAddress(); + } + + @Override + public String toString(Charset charset) { + return original.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + return original.toString(index, length, charset); + } + + @Override + public int compareTo(ByteBuf buffer) { + return original.compareTo(buffer); + } + + @Override + public String toString() { + return original.toString(); + } + + @Override + public ByteBuf retain(int increment) { + return original.retain(increment); + } + + @Override + public int refCnt() { + return original.refCnt(); + } + + @Override + public ByteBuf retain() { + return original.retain(); + } + + @Override + public ByteBuf touch() { + return original.touch(); + } + + @Override + public ByteBuf touch(Object hint) { + return original.touch(hint); + } + + @Override + public boolean release() { + return original.release(); + } + + @Override + public boolean release(int decrement) { + return original.release(decrement); + } + + + /* + * Need to rewrite this method to use cache identifier + */ + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + WrappedIdentifyByteBuf that = (WrappedIdentifyByteBuf) o; + return Objects.equals(identifier, that.identifier); + } + + @Override + public int hashCode() { + return Objects.hashCode(identifier); + } +} diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java index 1c6382b45..a8f84383b 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java @@ -26,6 +26,7 @@ import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.util.SpigotReflectionUtil; import io.github.retrooper.packetevents.util.folia.FoliaScheduler; @@ -73,6 +74,12 @@ public void read(ChannelHandlerContext ctx, ByteBuf input, List out) thr @Override public void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { if (buffer.isReadable()) { + + // Wrapped meta system + if (!(buffer instanceof WrappedIdentifyByteBuf)) { + buffer = new WrappedIdentifyByteBuf(buffer); + } + read(ctx, buffer, out); } } diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java index a43012816..9bb37aefa 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java @@ -31,6 +31,7 @@ import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.util.SpigotReflectionUtil; import io.github.retrooper.packetevents.util.folia.FoliaScheduler; @@ -69,6 +70,12 @@ public PacketEventsEncoder(ChannelHandler encoder) { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf byteBuf, List list) throws Exception { + + // Wrapped meta system + if (!(byteBuf instanceof WrappedIdentifyByteBuf)) { + byteBuf = new WrappedIdentifyByteBuf(byteBuf); + } + boolean needsRecompression = !handledCompression && handleCompression(ctx, byteBuf); handleClientBoundPacket(ctx.channel(), user, player, byteBuf, this.promise); diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java b/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java index 082b831da..10dfbcb18 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java @@ -19,231 +19,238 @@ package io.github.retrooper.packetevents.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorModernImpl implements ByteBufOperator { + + @Override + public Object create(Object original) { + return new WrappedIdentifyByteBuf((ByteBuf) original); + } + @Override public int capacity(Object buffer) { - return ((ByteBuf)buffer).capacity(); + return ((ByteBuf) buffer).capacity(); } @Override public Object capacity(Object buffer, int capacity) { - return ((ByteBuf)buffer).capacity(capacity); + return ((ByteBuf) buffer).capacity(capacity); } @Override public int readerIndex(Object buffer) { - return ((ByteBuf)buffer).readerIndex(); + return ((ByteBuf) buffer).readerIndex(); } @Override public Object readerIndex(Object buffer, int readerIndex) { - return ((ByteBuf)buffer).readerIndex(readerIndex); + return ((ByteBuf) buffer).readerIndex(readerIndex); } @Override public int writerIndex(Object buffer) { - return ((ByteBuf)buffer).writerIndex(); + return ((ByteBuf) buffer).writerIndex(); } @Override public Object writerIndex(Object buffer, int writerIndex) { - return ((ByteBuf)buffer).writerIndex(writerIndex); + return ((ByteBuf) buffer).writerIndex(writerIndex); } @Override public int readableBytes(Object buffer) { - return ((ByteBuf)buffer).readableBytes(); + return ((ByteBuf) buffer).readableBytes(); } @Override public int writableBytes(Object buffer) { - return ((ByteBuf)buffer).writableBytes(); + return ((ByteBuf) buffer).writableBytes(); } @Override public Object clear(Object buffer) { - return ((ByteBuf)buffer).clear(); + return ((ByteBuf) buffer).clear(); } @Override public byte readByte(Object buffer) { - return ((ByteBuf)buffer).readByte(); + return ((ByteBuf) buffer).readByte(); } @Override public short readShort(Object buffer) { - return ((ByteBuf)buffer).readShort(); + return ((ByteBuf) buffer).readShort(); } @Override public int readMedium(Object buffer) { - return ((ByteBuf)buffer).readMedium(); + return ((ByteBuf) buffer).readMedium(); } @Override public int readInt(Object buffer) { - return ((ByteBuf)buffer).readInt(); + return ((ByteBuf) buffer).readInt(); } @Override public long readUnsignedInt(Object buffer) { - return ((ByteBuf)buffer).readUnsignedInt(); + return ((ByteBuf) buffer).readUnsignedInt(); } @Override public long readLong(Object buffer) { - return ((ByteBuf)buffer).readLong(); + return ((ByteBuf) buffer).readLong(); } @Override public void writeByte(Object buffer, int value) { - ((ByteBuf)buffer).writeByte(value); + ((ByteBuf) buffer).writeByte(value); } @Override public void writeShort(Object buffer, int value) { - ((ByteBuf)buffer).writeShort(value); + ((ByteBuf) buffer).writeShort(value); } @Override public void writeMedium(Object buffer, int value) { - ((ByteBuf)buffer).writeMedium(value); + ((ByteBuf) buffer).writeMedium(value); } @Override public void writeInt(Object buffer, int value) { - ((ByteBuf)buffer).writeInt(value); + ((ByteBuf) buffer).writeInt(value); } @Override public void writeLong(Object buffer, long value) { - ((ByteBuf)buffer).writeLong(value); + ((ByteBuf) buffer).writeLong(value); } @Override public Object getBytes(Object buffer, int index, byte[] destination) { - return ((ByteBuf)buffer).getBytes(index, destination); + return ((ByteBuf) buffer).getBytes(index, destination); } @Override public short getUnsignedByte(Object buffer, int index) { - return ((ByteBuf)buffer).getUnsignedByte(index); + return ((ByteBuf) buffer).getUnsignedByte(index); } @Override public boolean isReadable(Object buffer) { - return ((ByteBuf)buffer).isReadable(); + return ((ByteBuf) buffer).isReadable(); } @Override public Object copy(Object buffer) { - return ((ByteBuf)buffer).copy(); + return ((ByteBuf) buffer).copy(); } @Override public Object duplicate(Object buffer) { - return ((ByteBuf)buffer).duplicate(); + return ((ByteBuf) buffer).duplicate(); } @Override public boolean hasArray(Object buffer) { - return ((ByteBuf)buffer).hasArray(); + return ((ByteBuf) buffer).hasArray(); } @Override public byte[] array(Object buffer) { - return ((ByteBuf)buffer).array(); + return ((ByteBuf) buffer).array(); } @Override public Object retain(Object buffer) { - return ((ByteBuf)buffer).retain(); + return ((ByteBuf) buffer).retain(); } @Override public Object retainedDuplicate(Object buffer) { - return ((ByteBuf)buffer).duplicate().retain(); + return ((ByteBuf) buffer).duplicate().retain(); } @Override public Object readSlice(Object buffer, int length) { - return ((ByteBuf)buffer).readSlice(length); + return ((ByteBuf) buffer).readSlice(length); } @Override public Object readBytes(Object buffer, byte[] destination, int destinationIndex, int length) { - return ((ByteBuf)buffer).readBytes(destination, destinationIndex, length); + return ((ByteBuf) buffer).readBytes(destination, destinationIndex, length); } @Override public Object readBytes(Object buffer, int length) { - return ((ByteBuf)buffer).readBytes(length); + return ((ByteBuf) buffer).readBytes(length); } @Override public Object writeBytes(Object buffer, Object src) { - return ((ByteBuf)buffer).writeBytes((ByteBuf) src); + return ((ByteBuf) buffer).writeBytes((ByteBuf) src); } @Override public Object writeBytes(Object buffer, byte[] bytes) { - return ((ByteBuf)buffer).writeBytes(bytes); + return ((ByteBuf) buffer).writeBytes(bytes); } @Override public Object writeBytes(Object buffer, byte[] bytes, int offset, int length) { - return ((ByteBuf)buffer).writeBytes(bytes, offset, length); + return ((ByteBuf) buffer).writeBytes(bytes, offset, length); } @Override public void readBytes(Object buffer, byte[] bytes) { - ((ByteBuf)buffer).readBytes(bytes); + ((ByteBuf) buffer).readBytes(bytes); } @Override public boolean release(Object buffer) { - return ((ByteBuf)buffer).release(); + return ((ByteBuf) buffer).release(); } @Override public int refCnt(Object buffer) { - return ((ByteBuf)buffer).refCnt(); + return ((ByteBuf) buffer).refCnt(); } @Override public Object skipBytes(Object buffer, int length) { - return ((ByteBuf)buffer).skipBytes(length); + return ((ByteBuf) buffer).skipBytes(length); } @Override public String toString(Object buffer, int index, int length, Charset charset) { - return ((ByteBuf)buffer).toString(index, length, charset); + return ((ByteBuf) buffer).toString(index, length, charset); } @Override public Object markReaderIndex(Object buffer) { - return ((ByteBuf)buffer).markReaderIndex(); + return ((ByteBuf) buffer).markReaderIndex(); } @Override public Object resetReaderIndex(Object buffer) { - return ((ByteBuf)buffer).resetReaderIndex(); + return ((ByteBuf) buffer).resetReaderIndex(); } @Override public Object markWriterIndex(Object buffer) { - return ((ByteBuf)buffer).markWriterIndex(); + return ((ByteBuf) buffer).markWriterIndex(); } @Override public Object resetWriterIndex(Object buffer) { - return ((ByteBuf)buffer).resetWriterIndex(); + return ((ByteBuf) buffer).resetWriterIndex(); } @Override diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java index 87e95810a..c1c0e77a4 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java @@ -26,6 +26,7 @@ import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.sponge.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.sponge.util.SpongeReflectionUtil; import io.netty.buffer.ByteBuf; @@ -63,6 +64,12 @@ public void read(ChannelHandlerContext ctx, ByteBuf input, List out) thr @Override public void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { if (buffer.isReadable()) { + + // Wrapped meta system + if (!(buffer instanceof WrappedIdentifyByteBuf)) { + buffer = new WrappedIdentifyByteBuf(buffer); + } + read(ctx, buffer, out); } } diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java index 0ff9fe5ea..38d9a40d4 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java @@ -28,6 +28,7 @@ import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.sponge.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.sponge.util.viaversion.CustomPipelineUtil; import io.netty.buffer.ByteBuf; @@ -63,6 +64,12 @@ public PacketEventsEncoder(ChannelHandler encoder) { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf byteBuf, List list) throws Exception { + + // Wrapped meta system + if (!(byteBuf instanceof WrappedIdentifyByteBuf)) { + byteBuf = new WrappedIdentifyByteBuf(byteBuf); + } + boolean needsRecompression = !handledCompression && handleCompression(ctx, byteBuf); handleClientBoundPacket(ctx.channel(), user, player, byteBuf, this.promise); diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java index 76f70a75e..a27726d74 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java @@ -19,11 +19,18 @@ package io.github.retrooper.packetevents.sponge.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; +import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorModernImpl implements ByteBufOperator { + + @Override + public Object create(Object original) { + return new WrappedIdentifyByteBuf((ByteBuf) original); + } + @Override public int capacity(Object buffer) { return ((ByteBuf)buffer).capacity(); From aa3bf5c34b3bd5d1ac174055edd8d683318136a2 Mon Sep 17 00:00:00 2001 From: Felipe Paschoal Bergamo <64669985+felipepasc@users.noreply.github.com> Date: Wed, 9 Apr 2025 00:00:14 -0300 Subject: [PATCH 2/5] fix(meta): adjust timestamp calculation in PacketWrapperMeta --- .../retrooper/packetevents/util/meta/PacketWrapperMeta.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java index 9a7a45319..a1f92e171 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java @@ -5,10 +5,11 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeUnit; public class PacketWrapperMeta { private final Map data = new HashMap<>(); - private final long timestamp = System.currentTimeMillis(); + private final long timestamp = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10); public void put(@NotNull String key, @NotNull Object value) { this.data.put(key, value); From 41f32149302b031c6f454be2598ae60c0079bc64 Mon Sep 17 00:00:00 2001 From: Felipe Paschoal Bergamo <64669985+felipepasc@users.noreply.github.com> Date: Wed, 9 Apr 2025 00:26:41 -0300 Subject: [PATCH 3/5] fix: remove WrappedIdentifyByteBuf --- .../netty/buffer/ByteBufHelper.java | 4 - .../netty/buffer/ByteBufOperator.java | 1 - .../util/meta/PacketWrapperMetaCache.java | 37 +- .../packetevents/wrapper/PacketWrapper.java | 3 - .../packetevents/handler/PacketDecoder.java | 6 - .../packetevents/handler/PacketEncoder.java | 6 - .../netty/buffer/ByteBufOperatorImpl.java | 6 - .../netty/bytebuf/WrappedIdentifyByteBuf.java | 951 ------------------ .../handlers/PacketEventsDecoder.java | 7 - .../handlers/PacketEventsEncoder.java | 9 - .../buffer/ByteBufOperatorModernImpl.java | 6 - .../handlers/PacketEventsDecoder.java | 7 - .../handlers/PacketEventsEncoder.java | 7 - .../buffer/ByteBufOperatorModernImpl.java | 6 - 14 files changed, 28 insertions(+), 1028 deletions(-) delete mode 100644 netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java diff --git a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java index 33aa1f754..6142d183a 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufHelper.java @@ -24,10 +24,6 @@ public class ByteBufHelper { - public static Object create(Object buffer) { - return PacketEvents.getAPI().getNettyManager().getByteBufOperator().create(buffer); - } - public static int capacity(Object buffer) { return PacketEvents.getAPI().getNettyManager().getByteBufOperator().capacity(buffer); } diff --git a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java index de2250dc5..5bc72c29b 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java +++ b/api/src/main/java/com/github/retrooper/packetevents/netty/buffer/ByteBufOperator.java @@ -21,7 +21,6 @@ import java.nio.charset.Charset; public interface ByteBufOperator { - Object create(Object original); int capacity(Object buffer); Object capacity(Object buffer, int capacity); diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java index bc9a7ce28..5a286e99d 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java @@ -8,22 +8,22 @@ import java.util.concurrent.*; public class PacketWrapperMetaCache { - private static final Map META_CACHE = new ConcurrentHashMap<>(); + private static final Map META_CACHE = new ConcurrentHashMap<>(); public static void setMeta(@NotNull Object buffer, @NotNull String key, @NotNull Object value) { - META_CACHE.computeIfAbsent(buffer, __ -> new PacketWrapperMeta()).put(key, value); + META_CACHE.computeIfAbsent(new IdentityKey(buffer), __ -> new PacketWrapperMeta()).put(key, value); } public static @NotNull Map getMeta(@NotNull Object buffer) { - return META_CACHE.computeIfAbsent(buffer, __ -> new PacketWrapperMeta()).get(); + return META_CACHE.computeIfAbsent(new IdentityKey(buffer), __ -> new PacketWrapperMeta()).get(); } public static void clean() { - Set toRemoveKeys = new HashSet<>(); + Set toRemoveKeys = new HashSet<>(); - META_CACHE.forEach((o, packetWrapperMeta) -> { + META_CACHE.forEach((identityKey, packetWrapperMeta) -> { if (packetWrapperMeta.isExpired()) { - toRemoveKeys.add(o); + toRemoveKeys.add(identityKey); } }); @@ -37,16 +37,35 @@ public static void clean() { @Override public @NotNull Thread newThread(@NotNull Runnable runnable) { Thread thread = new Thread(runnable); - thread.setName("packet-events - meta clean #" + counter++); thread.setDaemon(false); - return thread; } - }; ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(threadFactory); scheduledExecutorService.scheduleAtFixedRate(PacketWrapperMetaCache::clean, 0, 10, TimeUnit.SECONDS); } + + private static final class IdentityKey { + private final Object ref; + + public IdentityKey(Object ref) { + this.ref = ref; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IdentityKey that = (IdentityKey) o; + return this.ref == that.ref; + } + + @Override + public int hashCode() { + return System.identityHashCode(ref); + } + } } diff --git a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java index 3ea60fb17..e655c23b5 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java @@ -223,9 +223,6 @@ public final void prepareForSend(Object channel, boolean outgoing, boolean proxy buffer = ChannelHelper.pooledByteBuf(channel); } - // Rewrite buffer to a meta-system - this.buffer = ByteBufHelper.create(this.buffer); - // Wrapped meta system writeMeta(); 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 b8dd25226..6e589c353 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 @@ -21,7 +21,6 @@ import com.github.retrooper.packetevents.protocol.PacketSide; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; @@ -48,11 +47,6 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) return; } - // Wrapped meta system - if (!(msg instanceof WrappedIdentifyByteBuf)) { - msg = new WrappedIdentifyByteBuf(msg); - } - PacketEventsImplHelper.handlePacket(ctx.channel(), this.user, this.player, msg, false, this.side); 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 6a54d965f..eded37b8e 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,7 +21,6 @@ import com.github.retrooper.packetevents.protocol.PacketSide; import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; @@ -52,11 +51,6 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) return; } - // Wrapped meta system - if (!(in instanceof WrappedIdentifyByteBuf)) { - in = new WrappedIdentifyByteBuf(in); - } - PacketEventsImplHelper.handlePacket(ctx.channel(), this.user, this.player, in, false, this.side); if (in.isReadable()) { diff --git a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java index 262de1d6f..434dbf297 100644 --- a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java +++ b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/buffer/ByteBufOperatorImpl.java @@ -19,18 +19,12 @@ package io.github.retrooper.packetevents.impl.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorImpl implements ByteBufOperator { - @Override - public Object create(Object original) { - return new WrappedIdentifyByteBuf((ByteBuf) original); - } - @Override public int capacity(Object buffer) { return ((ByteBuf)buffer).capacity(); diff --git a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java b/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java deleted file mode 100644 index d9febc936..000000000 --- a/netty-common/src/main/java/io/github/retrooper/packetevents/impl/netty/bytebuf/WrappedIdentifyByteBuf.java +++ /dev/null @@ -1,951 +0,0 @@ -package io.github.retrooper.packetevents.impl.netty.bytebuf; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import io.netty.util.ByteProcessor; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.ScatteringByteChannel; -import java.nio.charset.Charset; -import java.util.Objects; -import java.util.UUID; - -public class WrappedIdentifyByteBuf extends ByteBuf { - private final UUID identifier; - private final ByteBuf original; - - public WrappedIdentifyByteBuf(ByteBuf original) { - this.identifier = UUID.randomUUID(); - this.original = original; - } - - @Override - public int capacity() { - return original.capacity(); - } - - @Override - public ByteBuf capacity(int newCapacity) { - return original.capacity(newCapacity); - } - - @Override - public int maxCapacity() { - return original.maxCapacity(); - } - - @Override - public ByteBufAllocator alloc() { - return original.alloc(); - } - - @Deprecated - @Override - public ByteOrder order() { - return original.order(); - } - - @Deprecated - @Override - public ByteBuf order(ByteOrder endianness) { - return original.order(endianness); - } - - @Override - public ByteBuf unwrap() { - return original.unwrap(); - } - - @Override - public boolean isDirect() { - return original.isDirect(); - } - - @Override - public boolean isReadOnly() { - return original.isReadOnly(); - } - - @Override - public ByteBuf asReadOnly() { - return original.asReadOnly(); - } - - @Override - public int readerIndex() { - return original.readerIndex(); - } - - @Override - public ByteBuf readerIndex(int readerIndex) { - return original.readerIndex(readerIndex); - } - - @Override - public int writerIndex() { - return original.writerIndex(); - } - - @Override - public ByteBuf writerIndex(int writerIndex) { - return original.writerIndex(writerIndex); - } - - @Override - public ByteBuf setIndex(int readerIndex, int writerIndex) { - return original.setIndex(readerIndex, writerIndex); - } - - @Override - public int readableBytes() { - return original.readableBytes(); - } - - @Override - public int writableBytes() { - return original.writableBytes(); - } - - @Override - public int maxWritableBytes() { - return original.maxWritableBytes(); - } - - @Override - public boolean isReadable() { - return original.isReadable(); - } - - @Override - public boolean isReadable(int numBytes) { - return original.isReadable(numBytes); - } - - @Override - public boolean isWritable() { - return original.isWritable(); - } - - @Override - public boolean isWritable(int numBytes) { - return original.isWritable(numBytes); - } - - @Override - public ByteBuf clear() { - return original.clear(); - } - - @Override - public ByteBuf markReaderIndex() { - return original.markReaderIndex(); - } - - @Override - public ByteBuf resetReaderIndex() { - return original.resetReaderIndex(); - } - - @Override - public ByteBuf markWriterIndex() { - return original.markWriterIndex(); - } - - @Override - public ByteBuf resetWriterIndex() { - return original.resetWriterIndex(); - } - - @Override - public ByteBuf discardReadBytes() { - return original.discardReadBytes(); - } - - @Override - public ByteBuf discardSomeReadBytes() { - return original.discardSomeReadBytes(); - } - - @Override - public ByteBuf ensureWritable(int minWritableBytes) { - return original.ensureWritable(minWritableBytes); - } - - @Override - public int ensureWritable(int minWritableBytes, boolean force) { - return original.ensureWritable(minWritableBytes, force); - } - - @Override - public boolean getBoolean(int index) { - return original.getBoolean(index); - } - - @Override - public byte getByte(int index) { - return original.getByte(index); - } - - @Override - public short getUnsignedByte(int index) { - return original.getUnsignedByte(index); - } - - @Override - public short getShort(int index) { - return original.getShort(index); - } - - @Override - public short getShortLE(int index) { - return original.getShortLE(index); - } - - @Override - public int getUnsignedShort(int index) { - return original.getUnsignedShort(index); - } - - @Override - public int getUnsignedShortLE(int index) { - return original.getUnsignedShortLE(index); - } - - @Override - public int getMedium(int index) { - return original.getMedium(index); - } - - @Override - public int getMediumLE(int index) { - return original.getMediumLE(index); - } - - @Override - public int getUnsignedMedium(int index) { - return original.getUnsignedMedium(index); - } - - @Override - public int getUnsignedMediumLE(int index) { - return original.getUnsignedMediumLE(index); - } - - @Override - public int getInt(int index) { - return original.getInt(index); - } - - @Override - public int getIntLE(int index) { - return original.getIntLE(index); - } - - @Override - public long getUnsignedInt(int index) { - return original.getUnsignedInt(index); - } - - @Override - public long getUnsignedIntLE(int index) { - return original.getUnsignedIntLE(index); - } - - @Override - public long getLong(int index) { - return original.getLong(index); - } - - @Override - public long getLongLE(int index) { - return original.getLongLE(index); - } - - @Override - public char getChar(int index) { - return original.getChar(index); - } - - @Override - public float getFloat(int index) { - return original.getFloat(index); - } - - @Override - public double getDouble(int index) { - return original.getDouble(index); - } - - @Override - public ByteBuf getBytes(int index, ByteBuf dst) { - return original.getBytes(index, dst); - } - - @Override - public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex) { - return original.getBytes(index, dst, dstIndex); - } - - @Override - public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { - return original.getBytes(index, dst, dstIndex, length); - } - - @Override - public ByteBuf getBytes(int index, byte[] dst) { - return original.getBytes(index, dst); - } - - @Override - public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - return original.getBytes(index, dst, dstIndex, length); - } - - @Override - public ByteBuf getBytes(int index, ByteBuffer dst) { - return original.getBytes(index, dst); - } - - @Override - public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { - return original.getBytes(index, out, length); - } - - @Override - public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { - return original.getBytes(index, out, length); - } - - @Override - public int getBytes(int index, FileChannel out, long position, int length) throws IOException { - return original.getBytes(index, out, position, length); - } - - @Override - public CharSequence getCharSequence(int index, int length, Charset charset) { - return original.getCharSequence(index, length, charset); - } - - @Override - public ByteBuf setBoolean(int index, boolean value) { - return original.setBoolean(index, value); - } - - @Override - public ByteBuf setByte(int index, int value) { - return original.setByte(index, value); - } - - @Override - public ByteBuf setShort(int index, int value) { - return original.setShort(index, value); - } - - @Override - public ByteBuf setShortLE(int index, int value) { - return original.setShortLE(index, value); - } - - @Override - public ByteBuf setMedium(int index, int value) { - return original.setMedium(index, value); - } - - @Override - public ByteBuf setMediumLE(int index, int value) { - return original.setMediumLE(index, value); - } - - @Override - public ByteBuf setInt(int index, int value) { - return original.setInt(index, value); - } - - @Override - public ByteBuf setIntLE(int index, int value) { - return original.setIntLE(index, value); - } - - @Override - public ByteBuf setLong(int index, long value) { - return original.setLong(index, value); - } - - @Override - public ByteBuf setLongLE(int index, long value) { - return original.setLongLE(index, value); - } - - @Override - public ByteBuf setChar(int index, int value) { - return original.setChar(index, value); - } - - @Override - public ByteBuf setFloat(int index, float value) { - return original.setFloat(index, value); - } - - @Override - public ByteBuf setDouble(int index, double value) { - return original.setDouble(index, value); - } - - @Override - public ByteBuf setBytes(int index, ByteBuf src) { - return original.setBytes(index, src); - } - - @Override - public ByteBuf setBytes(int index, ByteBuf src, int srcIndex) { - return original.setBytes(index, src, srcIndex); - } - - @Override - public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - return original.setBytes(index, src, srcIndex, length); - } - - @Override - public ByteBuf setBytes(int index, byte[] src) { - return original.setBytes(index, src); - } - - @Override - public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - return original.setBytes(index, src, srcIndex, length); - } - - @Override - public ByteBuf setBytes(int index, ByteBuffer src) { - return original.setBytes(index, src); - } - - @Override - public int setBytes(int index, InputStream in, int length) throws IOException { - return original.setBytes(index, in, length); - } - - @Override - public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - return original.setBytes(index, in, length); - } - - @Override - public int setBytes(int index, FileChannel in, long position, int length) throws IOException { - return original.setBytes(index, in, position, length); - } - - @Override - public ByteBuf setZero(int index, int length) { - return original.setZero(index, length); - } - - @Override - public int setCharSequence(int index, CharSequence sequence, Charset charset) { - return original.setCharSequence(index, sequence, charset); - } - - @Override - public boolean readBoolean() { - return original.readBoolean(); - } - - @Override - public byte readByte() { - return original.readByte(); - } - - @Override - public short readUnsignedByte() { - return original.readUnsignedByte(); - } - - @Override - public short readShort() { - return original.readShort(); - } - - @Override - public short readShortLE() { - return original.readShortLE(); - } - - @Override - public int readUnsignedShort() { - return original.readUnsignedShort(); - } - - @Override - public int readUnsignedShortLE() { - return original.readUnsignedShortLE(); - } - - @Override - public int readMedium() { - return original.readMedium(); - } - - @Override - public int readMediumLE() { - return original.readMediumLE(); - } - - @Override - public int readUnsignedMedium() { - return original.readUnsignedMedium(); - } - - @Override - public int readUnsignedMediumLE() { - return original.readUnsignedMediumLE(); - } - - @Override - public int readInt() { - return original.readInt(); - } - - @Override - public int readIntLE() { - return original.readIntLE(); - } - - @Override - public long readUnsignedInt() { - return original.readUnsignedInt(); - } - - @Override - public long readUnsignedIntLE() { - return original.readUnsignedIntLE(); - } - - @Override - public long readLong() { - return original.readLong(); - } - - @Override - public long readLongLE() { - return original.readLongLE(); - } - - @Override - public char readChar() { - return original.readChar(); - } - - @Override - public float readFloat() { - return original.readFloat(); - } - - @Override - public double readDouble() { - return original.readDouble(); - } - - @Override - public ByteBuf readBytes(int length) { - return original.readBytes(length); - } - - @Override - public ByteBuf readSlice(int length) { - return original.readSlice(length); - } - - @Override - public ByteBuf readRetainedSlice(int length) { - return original.readRetainedSlice(length); - } - - @Override - public ByteBuf readBytes(ByteBuf dst) { - return original.readBytes(dst); - } - - @Override - public ByteBuf readBytes(ByteBuf dst, int length) { - return original.readBytes(dst, length); - } - - @Override - public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { - return original.readBytes(dst, dstIndex, length); - } - - @Override - public ByteBuf readBytes(byte[] dst) { - return original.readBytes(dst); - } - - @Override - public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { - return original.readBytes(dst, dstIndex, length); - } - - @Override - public ByteBuf readBytes(ByteBuffer dst) { - return original.readBytes(dst); - } - - @Override - public ByteBuf readBytes(OutputStream out, int length) throws IOException { - return original.readBytes(out, length); - } - - @Override - public int readBytes(GatheringByteChannel out, int length) throws IOException { - return original.readBytes(out, length); - } - - @Override - public CharSequence readCharSequence(int length, Charset charset) { - return original.readCharSequence(length, charset); - } - - @Override - public int readBytes(FileChannel out, long position, int length) throws IOException { - return original.readBytes(out, position, length); - } - - @Override - public ByteBuf skipBytes(int length) { - return original.skipBytes(length); - } - - @Override - public ByteBuf writeBoolean(boolean value) { - return original.writeBoolean(value); - } - - @Override - public ByteBuf writeByte(int value) { - return original.writeByte(value); - } - - @Override - public ByteBuf writeShort(int value) { - return original.writeShort(value); - } - - @Override - public ByteBuf writeShortLE(int value) { - return original.writeShortLE(value); - } - - @Override - public ByteBuf writeMedium(int value) { - return original.writeMedium(value); - } - - @Override - public ByteBuf writeMediumLE(int value) { - return original.writeMediumLE(value); - } - - @Override - public ByteBuf writeInt(int value) { - return original.writeInt(value); - } - - @Override - public ByteBuf writeIntLE(int value) { - return original.writeIntLE(value); - } - - @Override - public ByteBuf writeLong(long value) { - return original.writeLong(value); - } - - @Override - public ByteBuf writeLongLE(long value) { - return original.writeLongLE(value); - } - - @Override - public ByteBuf writeChar(int value) { - return original.writeChar(value); - } - - @Override - public ByteBuf writeFloat(float value) { - return original.writeFloat(value); - } - - @Override - public ByteBuf writeDouble(double value) { - return original.writeDouble(value); - } - - @Override - public ByteBuf writeBytes(ByteBuf src) { - return original.writeBytes(src); - } - - @Override - public ByteBuf writeBytes(ByteBuf src, int length) { - return original.writeBytes(src, length); - } - - @Override - public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { - return original.writeBytes(src, srcIndex, length); - } - - @Override - public ByteBuf writeBytes(byte[] src) { - return original.writeBytes(src); - } - - @Override - public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { - return original.writeBytes(src, srcIndex, length); - } - - @Override - public ByteBuf writeBytes(ByteBuffer src) { - return original.writeBytes(src); - } - - @Override - public int writeBytes(InputStream in, int length) throws IOException { - return original.writeBytes(in, length); - } - - @Override - public int writeBytes(ScatteringByteChannel in, int length) throws IOException { - return original.writeBytes(in, length); - } - - @Override - public int writeBytes(FileChannel in, long position, int length) throws IOException { - return original.writeBytes(in, position, length); - } - - @Override - public ByteBuf writeZero(int length) { - return original.writeZero(length); - } - - @Override - public int writeCharSequence(CharSequence sequence, Charset charset) { - return original.writeCharSequence(sequence, charset); - } - - @Override - public int indexOf(int fromIndex, int toIndex, byte value) { - return original.indexOf(fromIndex, toIndex, value); - } - - @Override - public int bytesBefore(byte value) { - return original.bytesBefore(value); - } - - @Override - public int bytesBefore(int length, byte value) { - return original.bytesBefore(length, value); - } - - @Override - public int bytesBefore(int index, int length, byte value) { - return original.bytesBefore(index, length, value); - } - - @Override - public int forEachByte(ByteProcessor processor) { - return original.forEachByte(processor); - } - - @Override - public int forEachByte(int index, int length, ByteProcessor processor) { - return original.forEachByte(index, length, processor); - } - - @Override - public int forEachByteDesc(ByteProcessor processor) { - return original.forEachByteDesc(processor); - } - - @Override - public int forEachByteDesc(int index, int length, ByteProcessor processor) { - return original.forEachByteDesc(index, length, processor); - } - - @Override - public ByteBuf copy() { - return original.copy(); - } - - @Override - public ByteBuf copy(int index, int length) { - return original.copy(index, length); - } - - @Override - public ByteBuf slice() { - return original.slice(); - } - - @Override - public ByteBuf retainedSlice() { - return original.retainedSlice(); - } - - @Override - public ByteBuf slice(int index, int length) { - return original.slice(index, length); - } - - @Override - public ByteBuf retainedSlice(int index, int length) { - return original.retainedSlice(index, length); - } - - @Override - public ByteBuf duplicate() { - return original.duplicate(); - } - - @Override - public ByteBuf retainedDuplicate() { - return original.retainedDuplicate(); - } - - @Override - public int nioBufferCount() { - return original.nioBufferCount(); - } - - @Override - public ByteBuffer nioBuffer() { - return original.nioBuffer(); - } - - @Override - public ByteBuffer nioBuffer(int index, int length) { - return original.nioBuffer(index, length); - } - - @Override - public ByteBuffer internalNioBuffer(int index, int length) { - return original.internalNioBuffer(index, length); - } - - @Override - public ByteBuffer[] nioBuffers() { - return original.nioBuffers(); - } - - @Override - public ByteBuffer[] nioBuffers(int index, int length) { - return original.nioBuffers(index, length); - } - - @Override - public boolean hasArray() { - return original.hasArray(); - } - - @Override - public byte[] array() { - return original.array(); - } - - @Override - public int arrayOffset() { - return original.arrayOffset(); - } - - @Override - public boolean hasMemoryAddress() { - return original.hasMemoryAddress(); - } - - @Override - public long memoryAddress() { - return original.memoryAddress(); - } - - @Override - public String toString(Charset charset) { - return original.toString(charset); - } - - @Override - public String toString(int index, int length, Charset charset) { - return original.toString(index, length, charset); - } - - @Override - public int compareTo(ByteBuf buffer) { - return original.compareTo(buffer); - } - - @Override - public String toString() { - return original.toString(); - } - - @Override - public ByteBuf retain(int increment) { - return original.retain(increment); - } - - @Override - public int refCnt() { - return original.refCnt(); - } - - @Override - public ByteBuf retain() { - return original.retain(); - } - - @Override - public ByteBuf touch() { - return original.touch(); - } - - @Override - public ByteBuf touch(Object hint) { - return original.touch(hint); - } - - @Override - public boolean release() { - return original.release(); - } - - @Override - public boolean release(int decrement) { - return original.release(decrement); - } - - - /* - * Need to rewrite this method to use cache identifier - */ - - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) return false; - WrappedIdentifyByteBuf that = (WrappedIdentifyByteBuf) o; - return Objects.equals(identifier, that.identifier); - } - - @Override - public int hashCode() { - return Objects.hashCode(identifier); - } -} diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java index a8f84383b..1c6382b45 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsDecoder.java @@ -26,7 +26,6 @@ import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.util.SpigotReflectionUtil; import io.github.retrooper.packetevents.util.folia.FoliaScheduler; @@ -74,12 +73,6 @@ public void read(ChannelHandlerContext ctx, ByteBuf input, List out) thr @Override public void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { if (buffer.isReadable()) { - - // Wrapped meta system - if (!(buffer instanceof WrappedIdentifyByteBuf)) { - buffer = new WrappedIdentifyByteBuf(buffer); - } - read(ctx, buffer, out); } } diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java index 9bb37aefa..4ed4f5d23 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/injector/handlers/PacketEventsEncoder.java @@ -26,12 +26,9 @@ import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper; import com.github.retrooper.packetevents.protocol.ConnectionState; import com.github.retrooper.packetevents.protocol.player.User; -import com.github.retrooper.packetevents.util.EventCreationUtil; import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; -import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.util.SpigotReflectionUtil; import io.github.retrooper.packetevents.util.folia.FoliaScheduler; @@ -70,12 +67,6 @@ public PacketEventsEncoder(ChannelHandler encoder) { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf byteBuf, List list) throws Exception { - - // Wrapped meta system - if (!(byteBuf instanceof WrappedIdentifyByteBuf)) { - byteBuf = new WrappedIdentifyByteBuf(byteBuf); - } - boolean needsRecompression = !handledCompression && handleCompression(ctx, byteBuf); handleClientBoundPacket(ctx.channel(), user, player, byteBuf, this.promise); diff --git a/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java b/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java index 10dfbcb18..d6c81a0a7 100644 --- a/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java +++ b/spigot/src/main/java/io/github/retrooper/packetevents/netty/buffer/ByteBufOperatorModernImpl.java @@ -19,18 +19,12 @@ package io.github.retrooper.packetevents.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorModernImpl implements ByteBufOperator { - @Override - public Object create(Object original) { - return new WrappedIdentifyByteBuf((ByteBuf) original); - } - @Override public int capacity(Object buffer) { return ((ByteBuf) buffer).capacity(); diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java index c1c0e77a4..87e95810a 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsDecoder.java @@ -26,7 +26,6 @@ import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.sponge.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.sponge.util.SpongeReflectionUtil; import io.netty.buffer.ByteBuf; @@ -64,12 +63,6 @@ public void read(ChannelHandlerContext ctx, ByteBuf input, List out) thr @Override public void decode(ChannelHandlerContext ctx, ByteBuf buffer, List out) throws Exception { if (buffer.isReadable()) { - - // Wrapped meta system - if (!(buffer instanceof WrappedIdentifyByteBuf)) { - buffer = new WrappedIdentifyByteBuf(buffer); - } - read(ctx, buffer, out); } } diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java index 38d9a40d4..0ff9fe5ea 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/injector/handlers/PacketEventsEncoder.java @@ -28,7 +28,6 @@ import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.util.ExceptionUtil; import com.github.retrooper.packetevents.util.PacketEventsImplHelper; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.github.retrooper.packetevents.sponge.injector.connection.ServerConnectionInitializer; import io.github.retrooper.packetevents.sponge.util.viaversion.CustomPipelineUtil; import io.netty.buffer.ByteBuf; @@ -64,12 +63,6 @@ public PacketEventsEncoder(ChannelHandler encoder) { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf byteBuf, List list) throws Exception { - - // Wrapped meta system - if (!(byteBuf instanceof WrappedIdentifyByteBuf)) { - byteBuf = new WrappedIdentifyByteBuf(byteBuf); - } - boolean needsRecompression = !handledCompression && handleCompression(ctx, byteBuf); handleClientBoundPacket(ctx.channel(), user, player, byteBuf, this.promise); diff --git a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java index a27726d74..f920d7a58 100644 --- a/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java +++ b/sponge/src/main/java/io/github/retrooper/packetevents/sponge/netty/buffer/ByteBufOperatorModernImpl.java @@ -19,18 +19,12 @@ package io.github.retrooper.packetevents.sponge.netty.buffer; import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator; -import io.github.retrooper.packetevents.impl.netty.bytebuf.WrappedIdentifyByteBuf; import io.netty.buffer.ByteBuf; import java.nio.charset.Charset; public class ByteBufOperatorModernImpl implements ByteBufOperator { - @Override - public Object create(Object original) { - return new WrappedIdentifyByteBuf((ByteBuf) original); - } - @Override public int capacity(Object buffer) { return ((ByteBuf)buffer).capacity(); From 52b6edf2750b6172c084bd5307bfafe4885fb5b8 Mon Sep 17 00:00:00 2001 From: Felipe Paschoal Bergamo <64669985+felipepasc@users.noreply.github.com> Date: Wed, 9 Apr 2025 00:45:25 -0300 Subject: [PATCH 4/5] refactor(wrapper): improve code readability --- .../util/meta/PacketWrapperMetaCache.java | 26 ++++++++++--------- .../packetevents/wrapper/PacketWrapper.java | 8 +----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java index 5a286e99d..aab9071a1 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java @@ -1,32 +1,35 @@ package com.github.retrooper.packetevents.util.meta; import org.jetbrains.annotations.NotNull; - import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; public class PacketWrapperMetaCache { private static final Map META_CACHE = new ConcurrentHashMap<>(); public static void setMeta(@NotNull Object buffer, @NotNull String key, @NotNull Object value) { - META_CACHE.computeIfAbsent(new IdentityKey(buffer), __ -> new PacketWrapperMeta()).put(key, value); + META_CACHE.computeIfAbsent(new IdentityKey(buffer), unused -> new PacketWrapperMeta()) + .put(key, value); } public static @NotNull Map getMeta(@NotNull Object buffer) { - return META_CACHE.computeIfAbsent(new IdentityKey(buffer), __ -> new PacketWrapperMeta()).get(); + return META_CACHE.computeIfAbsent(new IdentityKey(buffer), unused -> new PacketWrapperMeta()) + .get(); } public static void clean() { Set toRemoveKeys = new HashSet<>(); - - META_CACHE.forEach((identityKey, packetWrapperMeta) -> { - if (packetWrapperMeta.isExpired()) { + META_CACHE.forEach((identityKey, meta) -> { + if (meta.isExpired()) { toRemoveKeys.add(identityKey); } }); - toRemoveKeys.forEach(META_CACHE::remove); } @@ -43,8 +46,8 @@ public static void clean() { } }; - ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(threadFactory); - scheduledExecutorService.scheduleAtFixedRate(PacketWrapperMetaCache::clean, 0, 10, TimeUnit.SECONDS); + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(threadFactory); + executor.scheduleAtFixedRate(PacketWrapperMetaCache::clean, 0, 10, TimeUnit.SECONDS); } private static final class IdentityKey { @@ -58,9 +61,8 @@ public IdentityKey(Object ref) { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - IdentityKey that = (IdentityKey) o; - return this.ref == that.ref; + return ref == that.ref; } @Override diff --git a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java index e655c23b5..5845352c0 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java @@ -116,14 +116,11 @@ public class PacketWrapper> { @ApiStatus.Internal public final Object bufferLock = new Object(); - // For use metadata packet system private final Map metadata = new HashMap<>(); protected ClientVersion clientVersion; protected ServerVersion serverVersion; - private final PacketTypeData packetTypeData; - // For sending chunk data packets, which need this data @Nullable protected User user; @@ -241,7 +238,6 @@ public final void prepareForSend(Object channel, boolean outgoing, boolean proxy } else { writeVarInt(packetTypeData.getNativePacketId()); } - write(); } @@ -274,7 +270,7 @@ public void readMeta() { public void writeMeta() { if (this.buffer != null) { - this.metadata.forEach((s, o) -> PacketWrapperMetaCache.setMeta(this.buffer, s, o)); + this.metadata.forEach((key, value) -> PacketWrapperMetaCache.setMeta(this.buffer, key, value)); } } @@ -294,8 +290,6 @@ public void copy(T wrapper) { //Current idea change server version, but still think more public final void readEvent(ProtocolPacketEvent event) { - - // Wrapped meta system readMeta(); PacketWrapper last = event.getLastUsedWrapper(); From 60ffe227bba74614c669d59bd0b8c91fd879c691 Mon Sep 17 00:00:00 2001 From: Felipe Paschoal Bergamo <64669985+felipepasc@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:20:50 -0300 Subject: [PATCH 5/5] feat(meta): refactor metadata handling in PacketWrapper ``` - Made metadata nullable and initialize it only when needed. - Updated setMeta to instantiate metadata if null. - Changed getMeta and hasMeta to utilize PacketWrapperMetaCache. - Removed unused methods and improved method signatures for clarity. ``` --- .../util/meta/PacketWrapperMeta.java | 8 ++--- .../util/meta/PacketWrapperMetaCache.java | 9 ++++-- .../packetevents/wrapper/PacketWrapper.java | 29 ++++++++++--------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java index a1f92e171..0d141419e 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMeta.java @@ -15,12 +15,12 @@ public void put(@NotNull String key, @NotNull Object value) { this.data.put(key, value); } - public @Nullable Object getMeta(@NotNull String key) { - return this.data.get(key); + public boolean has(@NotNull String key) { + return this.data.containsKey(key); } - public @NotNull Map get() { - return this.data; + public @Nullable Object get(@NotNull String key) { + return this.data.get(key); } public long getTimestamp() { diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java index aab9071a1..260c3175e 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java +++ b/api/src/main/java/com/github/retrooper/packetevents/util/meta/PacketWrapperMetaCache.java @@ -18,9 +18,14 @@ public static void setMeta(@NotNull Object buffer, @NotNull String key, @NotNull .put(key, value); } - public static @NotNull Map getMeta(@NotNull Object buffer) { + public static boolean hasMeta(@NotNull Object buffer, @NotNull String key) { return META_CACHE.computeIfAbsent(new IdentityKey(buffer), unused -> new PacketWrapperMeta()) - .get(); + .has(key); + } + + public static Object getMeta(@NotNull Object buffer, @NotNull String key) { + return META_CACHE.computeIfAbsent(new IdentityKey(buffer), unused -> new PacketWrapperMeta()) + .get(key); } public static void clean() { diff --git a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java index 5845352c0..f9565ada8 100644 --- a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java +++ b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java @@ -116,7 +116,8 @@ public class PacketWrapper> { @ApiStatus.Internal public final Object bufferLock = new Object(); - private final Map metadata = new HashMap<>(); + @Nullable + private Map metadata; protected ClientVersion clientVersion; protected ServerVersion serverVersion; @@ -247,29 +248,31 @@ public final void prepareForSend(Object channel, boolean outgoing) { } public void setMeta(@NotNull String key, @NotNull Object value) { + if (this.metadata == null) { + this.metadata = new HashMap<>(); + } + this.metadata.put(key, value); } public Object getMeta(@NotNull String key) { - return this.metadata.get(key); - } - - public boolean hasMeta(@NotNull String key) { - return this.metadata.containsKey(key); - } + if (this.buffer != null) { + return PacketWrapperMetaCache.getMeta(this.buffer, key); + } - public @NotNull Map getMetadata() { - return this.metadata; + return null; } - public void readMeta() { + public boolean hasMeta(@NotNull String key) { if (this.buffer != null) { - this.metadata.putAll(PacketWrapperMetaCache.getMeta(this.buffer)); + return PacketWrapperMetaCache.hasMeta(this.buffer, key); } + + return false; } public void writeMeta() { - if (this.buffer != null) { + if (this.buffer != null && this.metadata != null) { this.metadata.forEach((key, value) -> PacketWrapperMetaCache.setMeta(this.buffer, key, value)); } } @@ -290,8 +293,6 @@ public void copy(T wrapper) { //Current idea change server version, but still think more public final void readEvent(ProtocolPacketEvent event) { - readMeta(); - PacketWrapper last = event.getLastUsedWrapper(); if (last != null) { copy((T) last);