ProtocolLib

3M Downloads

Spamming ClientboundSetEquipmentPacket if it rewrited

KKW557 opened this issue ยท 3 comments

commented
  • This issue is not solved in a development build

Describe the bug
if rewrite context for PacketType.Play.Server.ENTITY_EQUIPMENT, server will spam this packet and client kicked by packet larger exception

under normal server only send once the packet when equip update
/packetlog this packet will see server still send packet when mainhand have a item

client kick log:

io.netty.handler.codec.DecoderException: java.io.IOException: Packet play/clientbound/minecraft:set_equipment (class_2744) was larger than I expected, found 53 bytes extra whilst reading packet clientbound/minecraft:set_equipment
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:499)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:202)
	at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:164)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.io.IOException: Packet play/clientbound/minecraft:set_equipment (class_2744) was larger than I expected, found 53 bytes extra whilst reading packet clientbound/minecraft:set_equipment
	at net.minecraft.class_2543.decode(class_2543.java:43)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
	... 39 more

To Reproduce

    @Override
    public void onEnable() {
        manager.addPacketListener(new PacketAdapter(this, PacketType.Play.Server.ENTITY_EQUIPMENT) {
            @Override
            public void onPacketSending(PacketEvent event) {
                modifyEquipments(event.getPacket(), event.getPlayer().locale());
            }
        });
    }

    private static void modifyEquipments(PacketContainer packet, Locale locale) {
        StructureModifier<List<Pair<EnumWrappers.ItemSlot, ItemStack>>> modifier = packet.getLists(BukkitConverters.getPairConverter(EnumWrappers.getItemSlotConverter(), BukkitConverters.getItemStackConverter()));
        for (int i = 0; i < modifier.getValues().size(); i++) {
            List<Pair<EnumWrappers.ItemSlot, ItemStack>> pairs = modifier.read(i);
            for (Pair<EnumWrappers.ItemSlot, ItemStack> pair : pairs) {
                ItemStack itemStack = pair.getSecond();
                if (itemStack.hasItemMeta()) {
                    ItemMeta itemMeta = itemStack.getItemMeta();
                    if (itemMeta.hasDisplayName()) {
                        itemMeta.displayName(GlobalTranslator.render(itemMeta.displayName(), locale));
                        itemStack.setItemMeta(itemMeta);
                    }
                }
            }
        }
    }

Expected behavior
server send modified packet

Version Info
Provide your ProtocolLib install info with /protocol dump through pastebin.

commented

server runs on Paper 1.21 and i debugged nms seems a wierd problem
ClientboundSetEquipmentPacket will send when livingentity detects an equipment changed, compare new item with LivingEntity#getLastHandItem if different, do LivingEntity#setLastHandItem(slot, newItem)
i breakpoint at setLastHandItem pre and post all can see item is not modified by what i mentioned modifyEquipments
but when i breakpoint getLastHandItem, in LivingEntity#lastHandItemStacks items is modified by modifyEquipments. Protocollib rewrite packet send to players should not be visible to server? i can find when lastHandItemStacks be modified

commented

server runs on Paper 1.21 and i debugged nms seems a wierd problem ClientboundSetEquipmentPacket will send when livingentity detects an equipment changed, compare new item with LivingEntity#getLastHandItem if different, do LivingEntity#setLastHandItem(slot, newItem) i breakpoint at setLastHandItem pre and post all can see item is not modified by what i mentioned modifyEquipments but when i breakpoint getLastHandItem, in LivingEntity#lastHandItemStacks items is modified by modifyEquipments. Protocollib rewrite packet send to players should not be visible to server? i can find when lastHandItemStacks be modified

How did you end up fixing it? I am currently having the same issues as you (trying to implement the same thing as you ๐Ÿ˜…)

commented

server runs on Paper 1.21 and i debugged nms seems a wierd problem ClientboundSetEquipmentPacket will send when livingentity detects an equipment changed, compare new item with LivingEntity#getLastHandItem if different, do LivingEntity#setLastHandItem(slot, newItem) i breakpoint at setLastHandItem pre and post all can see item is not modified by what i mentioned modifyEquipments but when i breakpoint getLastHandItem, in LivingEntity#lastHandItemStacks items is modified by modifyEquipments. Protocollib rewrite packet send to players should not be visible to server? i can find when lastHandItemStacks be modified

How did you end up fixing it? I am currently having the same issues as you (trying to implement the same thing as you ๐Ÿ˜…)

clone Itemstacks modify packet at end. Itemstacks in the packet is directed to the players inventory.