设置药水效果Packet时ID104抛出异常致玩家被踢出
解决ProtocolLib发送ENTITY_EFFECT数据包踢人问题
问题代码
PacketContainer hideplayer = new PacketContainer(PacketType.Play.Server.ENTITY_EFFECT); hideplayer.getIntegers().write(0, player.getEntityId()); hideplayer.getBytes().write(0, (byte) 14); hideplayer.getBytes().write(1, (byte) 1); hideplayer.getIntegers().write(1, 1);
问题描述
在Bukkit环境使用ProtocolLib,按wiki.vg文档配置PacketContainer发送上述数据包时,玩家被踢出服务器,报错如下:
错误日志
[00:26:11 ERROR]: Packet encoding of packet ID 104 threw (skippable? false) java.lang.IllegalArgumentException: Can't find id for 'null' in map Registry[ResourceKey[minecraft:root / minecraft:mob_effect] (Stable)] at net.minecraft.network.FriendlyByteBuf.writeId(FriendlyByteBuf.java:140) ~[?:?] at net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket.write(ClientboundUpdateMobEffectPacket.java:58) ~[?:?] at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:41) ~[paper-1.19.3.jar:git-Paper-371] at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:14) ~[paper-1.19.3.jar:git-Paper-371] at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:120) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.writeAndFlush(NettyChannelProxy.java:227) ~[ProtocolLib (1).jar:?] at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.writeAndFlush(NettyChannelProxy.java:233) ~[ProtocolLib (1).jar:?] at net.minecraft.network.Connection.doSendPacket(Connection.java:459) ~[?:?] at net.minecraft.network.Connection.lambda$sendPacket$11(Connection.java:433) ~[?:?] at com.comphenix.protocol.injector.netty.channel.NettyEventLoopProxy.lambda$proxyRunnable$2(NettyEventLoopProxy.java:48) ~[ProtocolLib (1).jar:?] at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.82.Final.jar:4.1.82.Final] at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.82.Final.jar:4.1.82.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.82.Final.jar:4.1.82.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.82.Final.jar:4.1.82.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.82.Final.jar:4.1.82.Final] at java.lang.Thread.run(Thread.java:833) ~[?:?] [00:26:11 INFO]: LorkLork5487 lost connection: Internal Exception: io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Can't find id for 'null' in map Registry[ResourceKey[minecraft:root / minecraft:mob_effect] (Stable)]
原因分析
错误核心是Can't find id for 'null' in map Registry[minecraft:mob_effect],说明数据包中的药水效果类型为null。1.19+版本中,ENTITY_EFFECT数据包(对应MC原生的ClientboundUpdateMobEffectPacket)不再支持直接用数字ID设置效果,需要传入完整的MobEffectInstance对象,旧版本手动写入字节/整数的方式会导致效果类型未正确初始化,出现null值。
修复代码
import org.bukkit.potion.MobEffect; import org.bukkit.potion.MobEffectInstance; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; // 创建隐身效果数据包 PacketContainer hideplayer = new PacketContainer(PacketType.Play.Server.ENTITY_EFFECT); // 设置目标玩家的实体ID hideplayer.getIntegers().write(0, player.getEntityId()); // 创建隐身效果实例:持续1秒(20刻),等级0 MobEffectInstance invisibilityEffect = new MobEffectInstance(MobEffect.INVISIBILITY, 20, 0); // 将效果实例写入数据包 hideplayer.getMobEffects().write(0, invisibilityEffect); // 发送数据包 try { ProtocolLibrary.getProtocolManager().sendServerPacket(player, hideplayer); } catch (Exception e) { e.printStackTrace(); }
说明
- 直接使用
getMobEffects()方法写入MobEffectInstance对象,是ProtocolLib适配1.19+版本的正确方式,能避免版本兼容问题。 - 如果需要其他效果,替换
MobEffect.INVISIBILITY为对应效果即可,比如MobEffect.SPEED。
内容的提问来源于stack exchange,提问作者EndermanPVP HK
相关产品推荐
相关产品推荐

