Cannot send any packet during PlayerLoginEvent
kyngs opened this issue ยท 3 comments
- This issue is not solved in a development build
Describe the bug
When attempting to send a packet in PlayerLoginEvent, the packet is not sent. Nothing appears in the logs, and nothing gets reported.
To Reproduce
Send a packet (LoginServerCustomPayload in my case) during PlayerLoginEvent.
Expected behavior
The packet gets sent
Screenshots
Not applicable
Version Info
https://pastebin.com/NVPfmupi
Additional context
Using a debugger, I've traced the issue to this part of the code:
the return value of getPlayerConnection()
is null, and thus the packet is silently not sent.
BTW, here's my code in case I'm doing something wrong:
@EventHandler
public void onLogin(PlayerLoginEvent event) {
for (MinecraftKey channel : loginChannels.keySet()) {
var container = new WrapperLoginServerCustomPayload();
container.setIdentifier(channel);
container.setData(Unpooled.buffer());
container.setTransactionId(getID(channel));
try {
logger.info("Sending login packet to " + event.getPlayer().getName() + " with channel " + channel);
manager.sendServerPacket(event.getPlayer(), container.getHandle());
} catch (Exception e) {
e.printStackTrace();
event.getPlayer().kick(Component.text("Internal server error"));
return;
}
}
}
EDIT: This appears to be caused by the server because the connection field is null when PlayerLoginEvent is fired. However, I remember this working fine on 1.18.2 last November when I was testing this.
I actually do not think sending packets in the login phase is currently implemented/supported. @derklaro Do you know if this could be implemented with moderate effort? I think the only option is to iterate through all connections in the
ServerConnectionListener
if the player object provided does not have a player connection.
Unfortunately, this is needed if I want to use the Login Plugin Message feature. I cannot send it in PreLogin because there is no Player object available (however, if I send the packet in a listener for LOGIN_START, the packet gets sent). But, I also cannot send it in PlayerJoinEvent, because at that moment, the protocol state is sent to PLAY. As in my edit, this worked fine in 1.18.2 last November, whether was it supported or not.
I actually do not think sending packets in the login phase is currently implemented/supported. @derklaro Do you know if this could be implemented with moderate effort? I think the only option is to iterate through all connections in the ServerConnectionListener
if the player object provided does not have a player connection.
I'm currently not sure where the injection of inbound channels is really happening. As far as I remember the login phase sniffing was implemented at some point, maybe there was an internal change that caused this to break?
In any case atm packet events do depend on the player object (or, more specifically the player uuid). When the client sends the login start packet with the uuid the injection will be done iirc. So it heavily depends on the packet order if we can change that behaviour, or, if we need some other (possibly breaking) way to do it.