SpigotMC / BungeeCord

BungeeCord, the 6th in a generation of server portal suites. Efficiently proxies and maintains connections and transport between multiple Minecraft servers.
https://www.spigotmc.org/go/bungeecord
Other
1.57k stars 1.11k forks source link

Sending plugin message to server on ServerSwitchEvent listener causes disconnect #3519

Closed Phoenix616 closed 1 year ago

Phoenix616 commented 1 year ago

Bungeecord version

git:BungeeCord-Bootstrap:1.20-R0.2-SNAPSHOT:f486a25:1737

Server version

3877-Spigot-17ca32d-f070277 (MC: 1.20.2)

Client version

1.20.2

Bungeecord plugins

BungeeResourcepacks

The bug

When switching servers you can get disconnected with several different errors. Some of those point to invalid packets in the CONFIGURATION phase (see the log for an error where this is pretty clear, there is also a similar but different error by a user of my plugin: https://hastebin.com/share/eqekunelay.css). The code point mentioned in this log is sending a plugin message with Server#sendData in a ServerSwitchListener.

This breaks how the API worked before and other things that could trigger packets to the server (or even client? seeing as the SystemChat packet is also mentioned in the error) in that phase might break too.

Possible solutions that I could think off:

Log output (links)

00:17:20 [SCHWERWIEGEND] [Phoenix616] <-> DownstreamBridge <-> [test] - encountered exception
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85)
    at net.md_5.bungee.ServerConnection$1.sendPacket(ServerConnection.java:39)
    at net.md_5.bungee.ServerConnection.sendData(ServerConnection.java:46)
    at de.themoep.resourcepacksplugin.bungee.BungeeResourcepacks.sendPackInfo(BungeeResourcepacks.java:791)
    at de.themoep.resourcepacksplugin.bungee.listeners.ServerSwitchListener.onServerSwitch(ServerSwitchListener.java:49)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19)
    at net.md_5.bungee.event.EventBus.post(EventBus.java:49)
    at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:413)
    at net.md_5.bungee.ServerConnector.cutThrough(ServerConnector.java:370)
    at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:153)
    at net.md_5.bungee.protocol.packet.LoginSuccess.handle(LoginSuccess.java:62)
    at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124)
    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.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.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.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.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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:813)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 54 more
00:17:20 [SCHWERWIEGEND] [Phoenix616] -> UpstreamBridge - encountered exception
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.SystemChat in phase CONFIGURATION with direction TO_CLIENT
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85)
    at net.md_5.bungee.UserConnection$1.sendPacket(UserConnection.java:150)
    at net.md_5.bungee.UserConnection.sendMessage(UserConnection.java:492)
    at net.md_5.bungee.UserConnection.sendMessage(UserConnection.java:520)
    at net.md_5.bungee.UserConnection.sendMessage(UserConnection.java:461)
    at net.md_5.bungee.UserConnection.sendMessage(UserConnection.java:449)
    at net.md_5.bungee.UserConnection.sendMessage(UserConnection.java:434)
    at net.md_5.bungee.connection.DownstreamBridge.exception(DownstreamBridge.java:105)
    at net.md_5.bungee.netty.HandlerBoss.exceptionCaught(HandlerBoss.java:202)
    at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346)
    at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325)
    at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.exceptionCaught(DefaultChannelPipeline.java:1377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346)
    at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325)
    at io.netty.channel.DefaultChannelPipeline.fireExceptionCaught(DefaultChannelPipeline.java:907)
    at io.netty.channel.VoidChannelPromise.fireException0(VoidChannelPromise.java:236)
    at io.netty.channel.VoidChannelPromise.tryFailure(VoidChannelPromise.java:178)
    at io.netty.util.internal.PromiseNotificationUtil.tryFailure(PromiseNotificationUtil.java:64)
    at io.netty.channel.AbstractChannelHandlerContext.notifyOutboundHandlerException(AbstractChannelHandlerContext.java:990)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:884)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85)
    at net.md_5.bungee.ServerConnection$1.sendPacket(ServerConnection.java:39)
    at net.md_5.bungee.ServerConnection.sendData(ServerConnection.java:46)
    at de.themoep.resourcepacksplugin.bungee.BungeeResourcepacks.sendPackInfo(BungeeResourcepacks.java:791)
    at de.themoep.resourcepacksplugin.bungee.listeners.ServerSwitchListener.onServerSwitch(ServerSwitchListener.java:49)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19)
    at net.md_5.bungee.event.EventBus.post(EventBus.java:49)
    at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:413)
    at net.md_5.bungee.ServerConnector.cutThrough(ServerConnector.java:370)
    at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:153)
    at net.md_5.bungee.protocol.packet.LoginSuccess.handle(LoginSuccess.java:62)
    at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124)
    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.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.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.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.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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.SystemChat in phase CONFIGURATION with direction TO_CLIENT
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:813)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 80 more

Alternative error: https://hastebin.com/share/eqekunelay.css

Checking

md-5 commented 1 year ago

Support configuration phase plugin messages directly

Pretty sure this is already the case. The issue is that this is happening in the login phase still. Likely the phase switch just needs to happen a bit earlier.

I don't think the event can be delayed until after the configuration phase because bungee needs to cut through to the client in that phase which means updating the players server (getServer) and the event needs to be fired when that happens to prevent plugins having an inconsistent view.

Brokkonaut commented 1 year ago

We have similar issues with ProxiedPlayer.sendMessage. When sending a message in PostLoginEvent, ServerConnectedEvent or ServerSwitchEvent the client gets disconnected with something like

[06:17:18] [Render thread/WARN]: Client disconnected with reason: Internal Exception: io.netty.handler.codec.DecoderException: net.minecraft.class151: Non [a-z0-9.-] character in namespace of location: {\"extra\":[{\"color\":\"gold\",\"text\":\"Willkommen, \"},{\"color\":\"white\",\"text\":\"Brokkonaut\"}],\"text\":\"\"}

I think the best way to fix this might be to queue those packets from sendMessage or sendData until the connection enters the correct phase

md-5 commented 1 year ago

I think sendMessage should be queued, but sendData should be able to be sent immediately subject to my above comment.

NEZNAMY commented 1 year ago

Delay the ServerSwitchEvent until after the configuration phase was done

I'm not sure about this solution, because then on server switch (not join) there would be a window for plugins to send packets during configuration phase still. Although delaying the event surely would help, it's not enough.

Solutions 1 and 3 would not fix other packets.

I believe the only way is to queue all game packets sent during configuration phase.

md-5 commented 1 year ago

What other packets?

NEZNAMY commented 1 year ago

Literally any. When I tried joining with my plugin, I got disconnected with any of the following based on enabled features:

io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.Team in phase CONFIGURATION with direction TO_CLIENT
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PlayerListHeaderFooter in phase CONFIGURATION with direction TO_CLIENT
md-5 commented 1 year ago

Is that part of the API?

NEZNAMY commented 1 year ago

ProxiedPlayer#setTabHeader indeed is a part of the API, the other one has to be sent directly due to a lack of API. Everything works fine for <1.20.2 players.

Outfluencer commented 1 year ago

if its not api its on the plugin devs side to get it fixed, but all api call should be fixed to work with plugins not specialy designed for 1.20.2

NEZNAMY commented 1 year ago

if its not api its on the plugin devs side to get it fixed, but all api call should be fixed to work with plugins not specialy designed for 1.20.2

How exactly are plugin devs supposed to fix it? How are they supposed to know when is the client in configuration phase and when not?

Outfluencer commented 1 year ago

looking into the bungeecord and minecraft soruce

NEZNAMY commented 1 year ago

looking into the bungeecord and minecraft soruce

Give me an example code then.

Phoenix616 commented 1 year ago

I don't think the event can be delayed until after the configuration phase because bungee needs to cut through to the client in that phase which means updating the players server (getServer) and the event needs to be fired when that happens to prevent plugins having an inconsistent view.

I'm not deep enough in Bungee internals to understand exactly why that would prevent the event from getting called later but from an API-design perspective the event is required to be fired after the configuration phase is done and the connection to the server is fully ready. Otherwise the contract that the API provides would be broken without any deprecation/change notice. (The contract being "Called when a player has changed servers.", not during the change)

And seeing as lots of other methods also cause issues when the client is not in the GAME phase I feel like that's the only way to get that event out of the LOGIN/CONFIGURATION phases into he GAME phase again.

md-5 commented 1 year ago

It has changed though? .getServer returns the new server and packets are actively proxied between the two?

I don't see how it could be otherwise

RedDiamondREC commented 1 year ago

I'm having basically the same issue https://gyazo.com/08969da01db49c004077d37c00174a53 only with people on 1.20.2 1.20.1 is fine (no issues I've seen on my non bungee server thats setup the same)

Phoenix616 commented 1 year ago

It has changed though? .getServer returns the new server and packets are actively proxied between the two?

I'm referring to the fact that the server connection is not completely ready to play the game (the "game" phase) when the ServerSwitchEvent is called. That's what I understand under "the server was changed": The player actually being able to play the game on the new server and the change process being completely done. Seeing as they can still be in the configuration or even login phase this is no longer true but was in the past.

Link0Darck commented 1 year ago

Good morning, I have neither viaversion nor geyser and I have the same problem. Thanks in advance !

Brokkonaut commented 1 year ago

It has changed though? .getServer returns the new server and packets are actively proxied between the two?

I'm referring to the fact that the server connection is not completely ready to play the game (the "game" phase) when the ServerSwitchEvent is called. That's what I understand under "the server was changed": The player actually being able to play the game on the new server and the change process being completely done. Seeing as they can still be in the configuration or even login phase this is no longer true but was in the past.

The configuration phase is different from the login phase, because the server can switch back to the configuration protocol at any time. So there is never a guarantee that a connection is in the play protocol in 1.20.2 even if it was in the play protocol and there was no server switch.

So I think all that could be done is a better way for plugins to support this (maybe with something like a ConnectionProtocolChangedEvent, an api to get the current protocol and the delaying of some packets (at least chat packets) until the connection has the correct protocol)

Phoenix616 commented 1 year ago

The configuration phase is different from the login phase, because the server can switch back to the configuration protocol at any time. So there is never a guarantee that a connection is in the play protocol in 1.20.2 even if it was in the play protocol and there was no server switch.

So I think all that could be done is a better way for plugins to support this (maybe with something like a ConnectionProtocolChangedEvent, an api to get the current protocol and the delaying of some packets (at least chat packets) until the connection has the correct protocol.

Of course an API for that would definitely be appreciated but this issue is about the changed behaviour of the ServerSwitchEvent which breaks basically any plugin using it to send any kind of data (seems that ProxiedPlayer#sendMessage might trigger this too).

I don't think expecting every plugin to implement some kind of after-server-switch caching to wait for the CONFIGURATION or LOGIN phases to go to the GAME phase again is the right approach.

The solution should be to either somehow call the event after the CONFIGURATION phase completed after a server switch or to queue any kind of GAME packet received in the LOGIN or CONFIGURATION phases until it switches back the the GAME phase. This could even prevent breaking if it switches to CONFIGURATION mid game. (Of course plugins messing with packets by themselves are on there own there and I wouldn't expect.them to be supported by this, just everything using the API.)

md-5 commented 1 year ago

I've implemented the queuing for API methods, I don't see any feasible way to change where the event is fired. Any other issues/suggestions should be a separate ticket.

Link0Darck commented 1 year ago

error

I'm coming back to this ticket again because I have this problem and I have the latest version of bungeecord (ver 1738) what should I do?

md-5 commented 1 year ago

Reproduce without plugins, bungee does not have a team API

HippieBeak commented 1 year ago

I'm also continuing to have problems...

Internal Exception: io.netty.handler.codec.DecoderException: java.io.IOException: Packet 0/0 (PacketPlayInTeleportAccept) was larger than I expected, found 34 bytes extra whilst reading packet 0

Will try to reproduce in the morning without plugins...

gre3x commented 1 year ago

My server is also still having this issue on latest version. Joining is fixed now, but when trying to switch servers I get kicked for Internal Exception: io.netty.handler.codec.DecoderException: java.io.IOException: Packet

Does this need a fix plugin side? If so, what would be potential the causes of this behavior?

Leahcimkrob commented 1 year ago

same issue with 1738 09:30:28 [SEVERE] [Bloody_Mind] -> UpstreamBridge - encountered exception io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.Kick in phase CONFIGURATION with direction TO_CLIENT at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881) at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940) at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:984) at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025) at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:306) at net.md_5.bungee.netty.ChannelWrapper.close(ChannelWrapper.java:121) at net.md_5.bungee.UserConnection.disconnect0(UserConnection.java:433) at net.md_5.bungee.UserConnection.disconnect(UserConnection.java:409) at net.md_5.bungee.connection.UpstreamBridge.exception(UpstreamBridge.java:63) at net.md_5.bungee.netty.HandlerBoss.exceptionCaught(HandlerBoss.java:202) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317) at io.netty.channel.ChannelHandlerAdapter.exceptionCaught(ChannelHandlerAdapter.java:92) at com.viaversion.viaversion.bungee.handlers.BungeeEncodeHandler.exceptionCaught(BungeeEncodeHandler.java:108) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317) at io.netty.channel.ChannelInboundHandlerAdapter.exceptionCaught(ChannelInboundHandlerAdapter.java:143) at com.viaversion.viaversion.bungee.handlers.BungeeDecodeHandler.exceptionCaught(BungeeDecodeHandler.java:61) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317) at io.netty.channel.DefaultChannelPipeline$HeadContext.exceptionCaught(DefaultChannelPipeline.java:1377) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346) at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325) at io.netty.channel.DefaultChannelPipeline.fireExceptionCaught(DefaultChannelPipeline.java:907) at io.netty.channel.VoidChannelPromise.fireException0(VoidChannelPromise.java:236) at io.netty.channel.VoidChannelPromise.tryFailure(VoidChannelPromise.java:178) at io.netty.util.internal.PromiseNotificationUtil.tryFailure(PromiseNotificationUtil.java:64) at io.netty.channel.AbstractChannelHandlerContext.notifyOutboundHandlerException(AbstractChannelHandlerContext.java:990) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:884) at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940) at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966) at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934) at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020) at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311) at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85) at net.md_5.bungee.UserConnection$1.sendPacket(UserConnection.java:152) at net.md_5.bungee.ServerConnector.handleLogin(ServerConnector.java:246) at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:194) at net.md_5.bungee.protocol.packet.Login.handle(Login.java:283) at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124) 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.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.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:333) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:454) 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.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.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509) at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407) 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:833) Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.Kick in phase CONFIGURATION with direction TO_CLIENT at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463) at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824) at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25) at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10) at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ... 73 more 09:30:28 [WARNING] No client connected for pending server! 09:30:28 [INFO] [Bloody_Mind] -> UpstreamBridge has disconnected 09:30:28 [INFO] [Bloody_Mind] <-> ServerConnector [lobby] has disconnected

Version: 09:31:12 [INFO] This server is running BungeeCord version git:BungeeCord-Bootstrap:1.20-R0.2-SNAPSHOT:0509303:1738 by md_5

md-5 commented 1 year ago

same issue with 1738

This is not the same issue, and its unclear what this issue is since the Kick packet is registered in phase CONFIGURATION with direction TO_CLIENT, so you need to provide more info in a separate ticket. ViaVersion is obviously not supported.

Leahcimkrob commented 1 year ago

same issue with 1738

This is not the same issue, and its unclear what this issue is since the Kick packet is registered in phase CONFIGURATION with direction TO_CLIENT, so you need to provide more info in a separate ticket. ViaVersion is obviously not supported.

ok, thank you. I will create a new ticket

MacTh3Mac commented 1 year ago

Trawling through GitHub, Spigot MC, Paper Discords and multiple other public discords, it would appear that there are a huge number of plugins / configurations affected by 1.20.2 clients unable to negotiate their way around a bungee cord network. Join event seems to get them into the worlds, but switching servers kicks them with a multitude of errors but all seem to relate to the client being in a GAME phase, and then having to go back in a CONFIGURATION phase again during switch and the packets not being handled &/or queued correctly.

Mojang is clear on their release notes that there has been a major re-write of the networking protocol, Im wondering, is this a larger fix than initially thought to ensure compatibility for newer and older clients on the same proxy.

from: https://www.minecraft.net/en-us/article/minecraft-java-edition-1-20-2

### NETWORK PROTOCOL

As part of ongoing work towards more data-driven features, the network protocol has been changed to include a new configuration phase.

- Configuration phase automatically starts after login phase (i.e. after client account has been verified) and lasts until the player joins the world (play phase)
- Clients can stay in configuration phase indefinitely - it's up to the server to release it to the world
- Servers can also request clients to re-enter the configuration phase after it has entered the play phase
_(Other players will see such clients as disconnected)_
- Users in configuration phase will not be visible on the player list

Actions allowed in configuration phase (moved from play phase):
 - Configuration of data-driven registries
 - Configuration of enabled features

Actions shared between configuration and play phases:
 - Application of server resource packs
 - Update of tags
 - Exchange of custom packets
 - Ping and keep-alive packets
 - Sending of client options

The server will now negotiate resource packs in the configuration phase
 -  This means that the player will no longer be in the world when answering prompts and reloading resources

I don't have the technical understanding of the protocol to be able to advise a fix, but can confirm a clean Bungee 1.20.2 with no plugins and any backend seems unaffected. But add one of many affected bungee plugins and the problem re-occurs.

If this isn't a fix on Bungeecord side and a tweak of packet scheduling, then I guess it will be a choice for us all to move many features and functions either to the backend instance or completely re-write Bungee plugins to work around this. Ideally the preferred solution would be a bungee side fix, so existing api's and methods continue to function irrespective of what client version is used to connect.

md-5 commented 1 year ago

You're gonna need to be more specific, the above commit 10 hours ago already fixed the mentioned APIs with issues.

MacTh3Mac commented 1 year ago

Error: https://pastebin.com/dUBUKpD8

I notice in a previous reply in this issue you mention that Team doesn't exist in Bungeecord, but it is referenced in: https://github.com/SpigotMC/BungeeCord/blob/master/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java

Disconnect message:

disconnected with: §fEncoderException : java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.Team in phase CONFIGURATION with direction TO_CLIENT @ io.netty.handler.codec.MessageToByteEncoder:125

NEZNAMY commented 1 year ago

The commit does not fix anything, not even the API.

Using the API gives me this (also thrown when using sendPacketQueued directly for other packets):

java.lang.NullPointerException: Cannot invoke "net.md_5.bungee.protocol.MinecraftEncoder.getProtocol()" because the return value of "io.netty.channel.ChannelPipeline.get(java.lang.Class)" is null
at net.md_5.bungee.netty.ChannelWrapper.getEncodeProtocol(ChannelWrapper.java:51)
at net.md_5.bungee.UserConnection.sendPacketQueued(UserConnection.java:184)
at net.md_5.bungee.UserConnection.setTabHeader(UserConnection.java:726)

When sendPacketQueued does not throw, the packet may get lost when sent during configuration phase (happens 100% of the time for scoreboard packets). Then, on server switch, I get disconnected with:

io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.StartConfiguration in phase CONFIGURATION with direction TO_CLIENT
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85)
    at net.md_5.bungee.UserConnection$1.sendPacket(UserConnection.java:152)
    at net.md_5.bungee.ServerConnector.cutThrough(ServerConnector.java:334)
    at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:153)
    at net.md_5.bungee.protocol.packet.LoginSuccess.handle(LoginSuccess.java:62)
    at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124)
    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.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.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.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.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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.StartConfiguration in phase CONFIGURATION with direction TO_CLIENT
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 44 more

or this

io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext$WriteTask.run(AbstractChannelHandlerContext.java:1247)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
    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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 10 more

or this

io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PlayerListItemUpdate in phase CONFIGURATION with direction TO_CLIENT
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext$WriteTask.run(AbstractChannelHandlerContext.java:1247)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
    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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PlayerListItemUpdate in phase CONFIGURATION with direction TO_CLIENT
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 10 more
Phoenix616 commented 1 year ago

Still getting the same error and kick on the latest BungeeCord (f9b75c4:1739). It looks to me like ServerConnection#sendData needs to also be queued until either a GAME or CONFIGURATION phase starts. (It not being supported in LOGIN makes sense but calling that in the ServerSwitchEvent was supported before)

As far as I can tell 0509303 only addressed the direction to the client, not to the server.

The "new" error (still the same as before):

21:52:19 [SCHWERWIEGEND] [Phoenix616] <-> DownstreamBridge <-> [lobby] - encountered exception
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:85)
    at net.md_5.bungee.ServerConnection$1.sendPacket(ServerConnection.java:39)
    at net.md_5.bungee.ServerConnection.sendData(ServerConnection.java:46)
    at de.themoep.resourcepacksplugin.bungee.BungeeResourcepacks.sendPackInfo(BungeeResourcepacks.java:808)
    at de.themoep.resourcepacksplugin.bungee.listeners.ServerSwitchListener.lambda$onServerSwitch$1(ServerSwitchListener.java:52)
    at de.themoep.resourcepacksplugin.bungee.listeners.ServerSwitchListener.onServerSwitch(ServerSwitchListener.java:72)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19)
    at net.md_5.bungee.event.EventBus.post(EventBus.java:49)
    at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:413)
    at net.md_5.bungee.ServerConnector.cutThrough(ServerConnector.java:370)
    at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:153)
    at net.md_5.bungee.protocol.packet.LoginSuccess.handle(LoginSuccess.java:62)
    at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124)
    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.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.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.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.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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PluginMessage in phase LOGIN with direction TO_SERVER
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:25)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 55 more
md-5 commented 1 year ago

@Phoenix616 see https://github.com/SpigotMC/BungeeCord/commit/497c6879e05d168102b3331e55c53ccfd9fef541

Phoenix616 commented 1 year ago

@Phoenix616 see 497c687

Ah, you managed to fix that while I was writing up the comment! This solved my issue, cheers!

HippieBeak commented 1 year ago

Unfortunately looks like I'm still having issues with the latest release...

Screenshot 2023-09-23 at 7 50 59 PM
io.netty.handler.codec.EncoderException: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PlayerListHeaderFooter in phase CONFIGURATION with direction TO_CLIENT
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:125)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:881)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:940)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:966)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:934)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311)
    at net.md_5.bungee.netty.ChannelWrapper.write(ChannelWrapper.java:90)
    at net.md_5.bungee.UserConnection$1.sendPacket(UserConnection.java:152)
    at codecrafter47.bungeetablistplus.handler.NewTabOverlayHandler.sendPacket(NewTabOverlayHandler.java:185)
    at codecrafter47.bungeetablistplus.handler.NewTabOverlayHandler.access$700(NewTabOverlayHandler.java:52)
    at codecrafter47.bungeetablistplus.handler.NewTabOverlayHandler$PassThroughContentHandler.onServerSwitch(NewTabOverlayHandler.java:501)
    at codecrafter47.bungeetablistplus.handler.NewTabOverlayHandler.onServerSwitch(NewTabOverlayHandler.java:270)
    at codecrafter47.bungeetablistplus.protocol.AbstractPacketHandler.onServerSwitch(AbstractPacketHandler.java:63)
    at codecrafter47.bungeetablistplus.protocol.AbstractPacketHandler.onServerSwitch(AbstractPacketHandler.java:63)
    at codecrafter47.bungeetablistplus.handler.RewriteLogic.onServerSwitch(RewriteLogic.java:138)
    at codecrafter47.bungeetablistplus.managers.TabViewManager.onServerConnected(TabViewManager.java:101)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19)
    at net.md_5.bungee.event.EventBus.post(EventBus.java:49)
    at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:413)
    at net.md_5.bungee.ServerConnector.cutThrough(ServerConnector.java:370)
    at net.md_5.bungee.ServerConnector.handle(ServerConnector.java:153)
    at net.md_5.bungee.protocol.packet.LoginSuccess.handle(LoginSuccess.java:62)
    at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:124)
    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.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.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.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.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.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
    at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407)
    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:833)
Caused by: java.lang.IllegalArgumentException: Cannot get ID for packet class net.md_5.bungee.protocol.packet.PlayerListHeaderFooter in phase CONFIGURATION with direction TO_CLIENT
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:463)
    at net.md_5.bungee.protocol.Protocol$DirectionData.getId(Protocol.java:824)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:26)
    at net.md_5.bungee.protocol.MinecraftEncoder.encode(MinecraftEncoder.java:10)
    at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
    ... 57 more
md-5 commented 1 year ago

bungeetablistplus is not using the API

gre3x commented 1 year ago

I am not using bungeetablistplus and I'm using the latest version of BungeeCord. I am still getting disconnected when trying to use plugin messaging to switch servers while using a 1.20.2 client.

Using a Bungee command like proxiedPlayer.connect(SERVER) works, but when trying to switch servers by using a "Connect" plugin message (aka via a Hub server GUI, NPC, etc) it gives this error on the sub-server that I am trying to connect to and kicks me:

[Disconnect] User Player1234 has disconnected, reason: Internal Exception: io.netty.handler.codec.DecoderException: java.io.IOException: Packet 0/19 (PacketPlayInLook) was larger than I expected, found 16 bytes extra whilst reading packet 19

This happens for any Paper server as the sub-server 1.8-1.19 from what I have tested (and latest ViaVersion installed)

Is there a fix for this? Do I need to open a new issue for this?

md-5 commented 1 year ago

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
    {
        Player player = (Player) sender;

        ByteArrayOutputStream b = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream( b );
        try
        {
            out.writeUTF( "Connect" );
            out.writeUTF( args[0] );
        } catch ( IOException ex )
        {
            // Impossible
        }

        player.sendPluginMessage( this, "BungeeCord", b.toByteArray() );

        return true;
    }

Works fine for me, and yes separate issues should be a separate ticket. Viaversion is also not supported.

Lewes commented 1 year ago

We are experiencing a similar error to gre3x's when a player switches server.

[Disconnect] User Player1234 has disconnected, reason: Internal Exception: io.netty.handler.codec.DecoderException: java.io.IOException: Packet 0/19 (PacketPlayInLook) was larger than I expected, found 16 bytes extra whilst reading packet 19

(quoted error from above)

However, it only seems to occur when the player is moving whilst switching server. If stationary, they're not kicked.

Parthodys commented 1 year ago

This issue shouldn't have been closed yet, as the issues still exist and this just creates confusion when its supposedly fixed when it is not. Running BungeeCord without any plugins is not much of a solution. Much of the point of BungeeCord are the plugins, many of which will likely not even receive updates, especially extensive updates.

If you need fundraising or something to get this stuff fixed, do let us know. We have players waiting and they are not very patient.

md-5 commented 1 year ago

You have provided no new information which suggests that it is not fixed.

RedDiamondREC commented 1 year ago

I am still getting this issue

md-5 commented 1 year ago

I am still getting this issue

Which issue? Where is your stack trace/logs?

NEZNAMY commented 1 year ago

Since this conversation is live now and I am not able to test it myself anytime soon, I'll ask. Was https://github.com/SpigotMC/BungeeCord/issues/3519#issuecomment-1732316872 fixed? I didn't receive any feedback on it.

md-5 commented 1 year ago

Since this conversation is live now and I am not able to test it myself anytime soon, I'll ask. Was #3519 (comment) fixed? I didn't receive any feedback on it.

No because it's not part of the API and also its not the subject of this issue.

NEZNAMY commented 1 year ago

ProxiedPlayer#setTabHeader is not part of the API? And if something isn't part of the API, does that mean it doesn't matter if it works or not?

md-5 commented 1 year ago

ProxiedPlayer#setTabHeader is not part of the API? And if something isn't part of the API, does that mean it doesn't matter if it works or not?

Apologies, that specific method has been fixed

NEZNAMY commented 1 year ago

In build 1751 when calling sendPacketQueued manually, the packet is lost when called during configuration phase.

md-5 commented 1 year ago
  1. That is not related to this ticket; 2. That method is not API; 3. You have not provided sufficient information to indicate what the issue is - that method is designed to queue packets during the login/configuration phase and works for this purpose as demonstrated by the original resolution of this ticket
NEZNAMY commented 1 year ago

Should I open a new issue? What should I do if there is no API?