ProtocolLib

3M Downloads

Can't cancel `PacketType.Handshake.Client.SET_PROTOCOL`

molor opened this issue ยท 10 comments

commented
  • This issue is not solved in a development build

Describe the bug

Cancellation of incoming packet(s?) just does nothing. Packet is still processed by the server. In my case, cancelling of SET_PROTOCOL should prevent the server from sending SERVER_INFO packet, but it will still be sent and ServerListPingEvent will still be called.

In older versions (1.18?) this cancellation was worked fine.

public MyPacketListener(SimplePlugin myPlugin) {
	super(new AdapterParameteters().
		plugin(myPlugin).
		types(PacketType.Handshake.Client.SET_PROTOCOL).
		listenerPriority(ListenerPriority.LOWEST)
	);
}
ProtocolLibrary.
	getProtocolManager().
	addPacketListener(new MyPacketListener(myPlugin));
@Override
public synchronized void onPacketReceiving(PacketEvent theEvent) {
	theEvent.setCancelled(true);
}

Expected behavior
Client can't ping the server in server list.

Version Info
Paper v1.20.4-493
PL v5.3.0-SNAPSHOT-723

Additional context
The problem is only with incoming packets. Outgoing packets can be cancelled w/o issues.

commented

In my case, after pinging the server in client server list w/ this:

@Override
public void onPacketReceiving(PacketEvent theEvent) {
	theEvent.setCancelled(true);
	System.out.println("Cancelled");
}

@EventHandler(priority = EventPriority.MONITOR)
public void handleEvent(ServerListPingEvent theEvent) {
	System.out.println("Processed");
}

In my server's console I got this:

[STDOUT] Cancelled
[STDOUT] Processed
commented

So the SET_PROTOCOL packet is still processed by the server, otherwise, it would not have sent a ping reply to the client?

commented

Are you using a clean spigot server to test this because it works fine for me? As you can see in the code the packet won't get processed if cancelled:

commented

Version Info
Paper v1.20.4-493

commented

I can also try on latest available build of Paper 1.20.4 too, but doubt that this will change something.
Can't test on 1.21 because my team isn't ready for such major update, and can't test on Spigot due to using Paper API methods

commented

That's not what I'm asking, I'm asking you to please confirm if this issue also occurs on a freshly setup spigot/paper 1.20.4 server without any other plugins than ProtocolLib and your test plugin? Maybe also provide the dump file for your test setup: /protocol dump

commented

Also PacketContainer#getProtocols() in latest PL version are just returns empty list for PacketType.Handshake.Client.SET_PROTOCOL packet.

In PL v5.2.0-SNAPSHOT-679 it was returned a correct protocol (status, login, ...).

commented

I just tried it and it works fine for me with the latest dev build:

protocolManager.addPacketListener(new PacketAdapter(this, PacketType.Handshake.Client.SET_PROTOCOL) {
	@Override
	public void onPacketReceiving(PacketEvent event) {
		System.out.println(event);
		System.out.println(event.getPacket().getClientIntents().readSafely(0));
		event.setCancelled(true);
	}
});

Regarding the getProtocols method that had to be changed since the handshake packet doesn't contain a protocol anymore and instead has a client intent field (getClientIntents).

commented

This is what I got on fresh Paper 1.20.4 server.

[STDOUT] Cancelled
Received class net.minecraft.network.protocol.status.PacketStatusInStart that couldn't be processed
java.lang.ClassCastException: class net.minecraft.server.network.HandshakeListener cannot be cast to class net.minecraft.network.protocol.status.PacketStatusInListener (net.minecraft.server.network.HandshakeListener and net.minecraft.network.protocol.status.PacketStatusInListener are in unnamed module of loader java.net.URLClassLoader @4cdf35a9)
        at net.minecraft.network.protocol.status.ServerboundStatusRequestPacket.handle(ServerboundStatusRequestPacket.java:8) ~[?:?]
        at net.minecraft.network.Connection.genericsFtw(Connection.java:313) ~[?:?]
        at net.minecraft.network.Connection.channelRead0(Connection.java:294) ~[?:?]
        at net.minecraft.network.Connection.channelRead0(Connection.java:61) ~[?:?]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:202) ~[netty-handler-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:164) ~[netty-handler-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at com.comphenix.protocol.injector.netty.channel.InboundPacketInterceptor.channelRead(InboundPacketInterceptor.java:42) ~[ProtocolLib.jar:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at com.comphenix.protocol.injector.netty.channel.InboundProtocolReader.channelRead(InboundProtocolReader.java:25) ~[ProtocolLib.jar:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at net.minecraft.server.network.LegacyQueryHandler.channelRead(LegacyQueryHandler.java:114) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) ~[netty-handler-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:152) ~[netty-handler-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[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.lang.Thread.run(Thread.java:833) ~[?:?]
[STDOUT] Processed

Dump:

ProtocolLib Dump
Timestamp: 07/16/24 17:07:07

ProtocolLib Version: ProtocolLib v5.3.0-SNAPSHOT-723
Bukkit Version: 1.20.4-R0.1-SNAPSHOT
Server Version: git-Paper-493 (MC: 1.20.4)
Java Version: 17.0.6

ProtocolLib: com.comphenix.protocol.ProtocolLib@3438e952[
  statistics=<null>
  packetTask=com.comphenix.protocol.scheduler.DefaultTask@68145389
  tickCounter=1948
  configExpectedMod=1
  updater=com.comphenix.protocol.updater.SpigotUpdater@1b1545a0
  redirectHandler=com.comphenix.protocol.ProtocolLib$2@58166d6e
  scheduler=com.comphenix.protocol.scheduler.DefaultScheduler@37ad4784
  commandProtocol=com.comphenix.protocol.CommandProtocol@7d6fd2e3
  commandPacket=com.comphenix.protocol.CommandPacket@4c66a0ab
  commandFilter=com.comphenix.protocol.CommandFilter@2770c954
  packetLogging=com.comphenix.protocol.PacketLogging@7abc3b59
  skipDisable=false
  isEnabled=true
  loader=io.papermc.paper.plugin.manager.DummyBukkitPluginLoader@79470627
  server=CraftServer{serverName=Paper,serverVersion=git-Paper-493,minecraftVersion=1.20.4}
  file=plugins\ProtocolLib.jar
  description=org.bukkit.plugin.PluginDescriptionFile@21c6c16a
  pluginMeta=org.bukkit.plugin.PluginDescriptionFile@21c6c16a
  dataFolder=plugins\ProtocolLib
  classLoader=PluginClassLoader{plugin=ProtocolLib v5.3.0-SNAPSHOT-723, pluginEnabled=true, url=plugins\ProtocolLib.jar}
  naggable=true
  newConfig=YamlConfiguration[path='', root='YamlConfiguration']
  configFile=plugins\ProtocolLib\config.yml
  logger=com.destroystokyo.paper.utils.PaperPluginLogger@7b0c0fa6
  lifecycleEventManager=io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEventManager@172fbde9
  allowsLifecycleRegistration=false
]
Manager: com.comphenix.protocol.injector.PacketFilterManager@75f3f7[
  plugin=ProtocolLib v5.3.0-SNAPSHOT-723
  server=CraftServer{serverName=Paper,serverVersion=git-Paper-493,minecraftVersion=1.20.4}
  reporter=com.comphenix.protocol.ProtocolLib$1@60a94f81
  minecraftVersion=(MC: 1.20.4)
  asyncFilterManager=com.comphenix.protocol.async.AsyncFilterManager@7bc31d0d
  pluginVerifier=com.comphenix.protocol.injector.PluginVerifier@11e93769
  mainThreadPacketTypes=com.comphenix.protocol.concurrent.PacketTypeListenerSet@3eac94e8
  inboundListeners=com.comphenix.protocol.injector.collection.InboundPacketListenerSet@14d311fb
  outboundListeners=com.comphenix.protocol.injector.collection.OutboundPacketListenerSet@771b4d19
  registeredListeners=[PacketAdapter[plugin=Tweaks, sending=EMPTY_WHITELIST, receiving=ListeningWhitelist[priority=LOWEST, packets=[SET_PROTOCOL[class=PacketHandshakingInSetProtocol, id=0]], gamephase=PLAYING, options=[]]]]
  networkManagerInjector=com.comphenix.protocol.injector.netty.manager.NetworkManagerInjector@2f117eec
  debug=false
  closed=false
  injected=true
]

Listeners:
molor.plugin.tweaks.changes.server.DoTest@5d4453a7[
  thePlugin=Tweaks v2.301
  plugin=Tweaks v2.301
  connectionSide=CLIENT_SIDE
  receivingWhitelist=ListeningWhitelist[priority=LOWEST, packets=[SET_PROTOCOL[class=PacketHandshakingInSetProtocol, id=0]], gamephase=PLAYING, options=[]]
  sendingWhitelist=EMPTY_WHITELIST
]

Plugins Using ProtocolLib:
Tweaks by [molor]
commented

The exception you are encountering is expected behavior due to the client sending the status request packet immediately after the handshake packet. This sequence cannot be processed by the handshake listener, leading to the exception. To prevent this from happening, you need to disconnect the player. You can achieve this by using:

event.getPlayer().kickPlayer("Reason for disconnecting");

This will stop the exception from occurring by disconnecting the player before the problematic packet sequence can be processed.

Additionally, it's important to be aware that Mojang has implemented a legacy ping handler in both the server and client. This means that even if you block the handshake packet, the server will still respond using the old format. For more details on this, you can refer to the Server List Ping documentation.