dmulloy2 / ProtocolLib

Provides read and write access to the Minecraft protocol with Bukkit.
GNU General Public License v2.0
1.04k stars 257 forks source link

Player disconnected when sending clientbound/minecraft:set_entity_data packet (Error sending packet clientbound/minecraft:set_entity_data (skippable? false)) #2987

Open Ghost-chu opened 5 months ago

Ghost-chu commented 5 months ago

Describe the bug A clear and concise description of what the bug is.

When plugin sending a series about spawn item entity packets to player, the player get disconnected due an ClassCastException.

Error sending packet clientbound/minecraft:set_entity_data (skippable? false)

[23:45:01 ERROR]: Error sending packet clientbound/minecraft:set_entity_data (skippable? false)
io.netty.handler.codec.EncoderException: Failed to encode packet 'clientbound/minecraft:set_entity_data'
        at net.minecraft.network.codec.IdDispatchCodec.encode(IdDispatchCodec.java:53) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.codec.IdDispatchCodec.encode(IdDispatchCodec.java:20) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:26) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:12) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:113) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:120) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.ChannelOutboundHandlerAdapter.write(ChannelOutboundHandlerAdapter.java:113) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at net.minecraft.network.Connection$2.write(Connection.java:750) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:863) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:968) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:856) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.DefaultChannelPipeline.write(DefaultChannelPipeline.java:1015) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannel.write(AbstractChannel.java:301) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at ProtocolLib (3).jar/com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.write(NettyChannelProxy.java:210) ~[ProtocolLib (3).jar:?]
        at ProtocolLib (3).jar/com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.write(NettyChannelProxy.java:199) ~[ProtocolLib (3).jar:?]
        at net.minecraft.network.Connection.doSendPacket(Connection.java:505) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.Connection.lambda$sendPacket$13(Connection.java:490) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at ProtocolLib (3).jar/com.comphenix.protocol.injector.netty.channel.NettyEventLoopProxy.lambda$proxyRunnable$2(NettyEventLoopProxy.java:48) ~[ProtocolLib (3).jar:?]
        at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
Caused by: java.lang.ClassCastException: class org.bukkit.craftbukkit.inventory.CraftItemStack cannot be cast to class net.minecraft.world.item.ItemStack (org.bukkit.craftbukkit.inventory.CraftItemStack and net.minecraft.world.item.ItemStack are in unnamed module of loader java.net.URLClassLoader @484b61fc)
        at net.minecraft.world.item.ItemStack$1.encode(ItemStack.java:157) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.syncher.SynchedEntityData$DataValue.write(SynchedEntityData.java:226) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket.pack(ClientboundSetEntityDataPacket.java:24) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket.write(ClientboundSetEntityDataPacket.java:44) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.codec.StreamCodec$2.encode(StreamCodec.java:38) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.codec.StreamCodec$5.encode(StreamCodec.java:88) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        at net.minecraft.network.codec.StreamCodec$5.encode(StreamCodec.java:78) ~[paper-1.20.6.jar:1.20.6-137-bd5867a]
        ... 39 more
[23:45:01 INFO]: Ghost_chu lost connection: Internal Exception: io.netty.handler.codec.EncoderException: Failed to encode packet 'clientbound/minecraft:set_entity_data'

To Reproduce

        sendPacketToAll(fakeItemSpawnPacket);
        sendPacketToAll(fakeItemMetaPacket);
        sendPacketToAll(fakeItemVelocityPacket);
    @Override
    public @NotNull PacketContainer createFakeItemSpawnPacket(int entityID, @NotNull Location displayLocation) {
        //First, create a new packet to spawn item
        PacketContainer fakeItemPacket = manager.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY);
        //and add data based on packet class in NMS  (global scope variable)
        //Reference: https://wiki.vg/Protocol#Spawn_Object
        fakeItemPacket.getIntegers()
                //Entity ID
                .write(0, entityID);
        //Velocity x
        fakeItemPacket.getEntityTypeModifier().write(0, EntityType.ITEM);
        //UUID
        fakeItemPacket.getUUIDs().write(0, UUID.randomUUID());
        //Location
        fakeItemPacket.getDoubles()
                //X
                .write(0, displayLocation.getX())
                //Y
                .write(1, displayLocation.getY())
                //Z
                .write(2, displayLocation.getZ());
        return fakeItemPacket;
    }

    @Override
    public @NotNull PacketContainer createFakeItemMetaPacket(int entityID, @NotNull ItemStack itemStack) {
        //Next, create a new packet to update item data (default is empty)
        PacketContainer fakeItemMetaPacket = manager.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
        //Entity ID
        fakeItemMetaPacket.getIntegers().write(0, entityID);

        //List<DataWatcher$Item> Type are more complex
        //Create a DataWatcher
        WrappedDataWatcher wpw = new WrappedDataWatcher();
        //https://wiki.vg/index.php?title=Entity_metadata#Entity
        if (plugin.getConfig().getBoolean("shop.display-item-use-name")) {
            String itemName = GsonComponentSerializer.gson().serialize(Util.getItemStackName(itemStack));
            wpw.setObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true), Optional.of(WrappedChatComponent.fromJson(itemName).getHandle()));
            wpw.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, WrappedDataWatcher.Registry.get(Boolean.class)), true);
        }

        //Must in the certain slot:https://wiki.vg/Entity_metadata#Item
        wpw.setObject(8, WrappedDataWatcher.Registry.getItemStackSerializer(false), itemStack);
        //Add it
        //For 1.19.2+, we need to use DataValue instead of WatchableObject
        //Check for new version protocolLib
        try {
            Class.forName("com.comphenix.protocol.wrappers.WrappedDataValue");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Unable to initialize packet, ProtocolLib update needed", e);
        }
        //Convert List<WrappedWatchableObject> to List<WrappedDataValue>
        List<WrappedWatchableObject> wrappedWatchableObjects = wpw.getWatchableObjects();
        List<WrappedDataValue> wrappedDataValues = new java.util.LinkedList<>();
        for (WrappedWatchableObject wrappedWatchableObject : wrappedWatchableObjects) {
            WrappedDataWatcher.WrappedDataWatcherObject watchableObject = wrappedWatchableObject.getWatcherObject();
            wrappedDataValues.add(new WrappedDataValue(watchableObject.getIndex(), watchableObject.getSerializer(), wrappedWatchableObject.getRawValue()));
        }
        fakeItemMetaPacket.getDataValueCollectionModifier().write(0, wrappedDataValues);
        return fakeItemMetaPacket;
    }

    @Override
    public @NotNull PacketContainer createFakeItemVelocityPacket(int entityID) {
        //And, create a entity velocity packet to make it at a proper location (otherwise it will fly randomly)
        PacketContainer fakeItemVelocityPacket = manager.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_VELOCITY);
        fakeItemVelocityPacket.getIntegers()
                //Entity ID
                .write(0, entityID)
                //Velocity x
                .write(1, 0)
                //Velocity y
                .write(2, 0)
                //Velocity z
                .write(3, 0);
        return fakeItemVelocityPacket;
    }

Expected behavior A clear and concise description of what you expected to happen.

The error shouldn't appears.

Screenshots If applicable, add screenshots to help explain your problem.

image

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

[dump-2024-06-07_23.47.42.txt](https://github.com/user-attachments/files/15741983/dump-2024-06-07_23.47.42.txt)

Additional context Add any other context about the problem here.

[23:50:08 INFO]: This server is running Paper version 1.20.6-137-master@bd5867a (2024-06-04T21:04:28Z) (Implementing API version 1.20.6-R0.1-SNAPSHOT)
You are running the latest version
Previous version: git-Paper-49 (MC: 1.20.6)
>
dmulloy2 commented 5 months ago

Thank you for the detailed report. It seems like at some point, the Bukkit item stack is not being converted into a NMS stack. I will look into this further

dmulloy2 commented 5 months ago

Give build 710 a try. I also added some helper methods to clean things up a little bit. Probably won't be able to use those right away, but maybe something to look forward to

xtb7 commented 5 months ago

Give build 710 a try. I also added some helper methods to clean things up a little bit. Probably won't be able to use those right away, but maybe something to look forward to

I also experienced this error. Build 716 seems to work for me, but later ones don't.

trisout78 commented 3 months ago

Hey @xtb7 do you have the 716 build please?

xtb7 commented 3 months ago

Hey @xtb7 do you have the 716 build please?

@trisout78 Yes, I do,but the latest dev build also seems to work. Here it is: https://ci.dmulloy2.net/job/ProtocolLib/726/

XXJNOTFOUND commented 3 months ago

mine is 726 but still show "Failed to encode packet 'clientbound/minecraft:set_entity_data'"

xtb7 commented 3 months ago

It doesn't happen for me. Here's the 716 build, though: ProtocolLib.zip

LostUmbrella58 commented 2 months ago

Hey guys, any new progress about this issue? It seems like similar issue happened again in both latest 1.20.4 stable build and latest dev build (so both in 1.20.4 server and 1.21.1 server).

The situation is: I want to make a special glow effect, which only make entites glowing to specified players.For example, we are playing bedwars, and we are in the same team, in this case, you can see me glowing but our enemies can't. So, at first, I tried to achieve by handling with Entity_Effect but failed. image image

Then I tried to use Entity_Metadata, but also failed ... image image

image

So could somebody help me out, whether it's my fault or not? Thanks!