Open tadhunt opened 1 year ago
Thank you for the detailed information!
By just looking at the provided info and knowing how the API works internally, I expect this to the result of a race condition.
Currently Geyser relies on a specific packet to know the uuid and username of the Bedrock player, and almost immediately after Velocity sent that packet PlayerChooseInitialServerEvent
is fired.
Before Geyser receives that specific packet, Geyser sees that connection as a 'pending' connection and makes a guess at the uuid and username it expects depending on the selected auth-type.
#onlineConnections()
includes all players on Geyser (both 'pending' and 'connected') and the other methods including #connectionByUuid(UUID)
only includes 'connected' players which would explain why #onlineConnections()
is working all the time and #connectionByUuid(UUID)
isn't.
This is only a theory, I haven't had the time to test it yet.
If this is the case, the following behavior could be observed:
PlayerChooseInitialServerEvent
, #connectionByUuid(UUID)
should work all the time#onlineConnections()
workaround should fail as well
Describe the bug
I'm creating a Velocity plugin dependent on Geyser (using the latest releases at the time of writing) for running some special business logic for choosing different servers for bedrock vs java players at connection time.
As per the Velocity docs, I'm receiving a
PlayerChooseInitialServerEvent
, and as per the Geyser wiki Using Geyser or Floodgate as a dependency, I'm attempting to determine if the player is a bedrock player connected through Geyser via:However, this is at best flaky. Sometimes it finds the connection, but most of the time it doesn't. If use
GeyserApi.api().onlineConnections()
and iterate myself through the returned list, it consistently finds Bedrock connections accurately.I can easily reproduce, but I'm not a Java expert, so getting am lost figuring out where the connectionsByUuid() function is failing.
For now, I'm use an
onlineConnections()
iterator comparing returned uuids instead of callingconnectionByUuid()
since that method seems to be reliable.Code to reproduce is below.
To Reproduce
This is the core of the implementation of choosing a different server for bedrock vs java players, and it exhibits the issue. You can find the full plugin implementation at https://github.com/tadhunt/VelocityGeyserTransfer.
Expected behaviour
My expectation is that when I have a UUID for a player, that
return a non-null
GeyserConnection
when the givenuuid
represents a Bedrock player connected to Velocity via Geyser.Screenshots / Videos
PII has been replaced with NNNN, UUUU, and XXXX, otherwise this velocity console log is unchanged.
Server Version and Plugins
Geyser Dump
No response
Geyser Version
[12:20:56 INFO]: This server is running Geyser version 2.1.0-SNAPSHOT (git-player-transfer-b27b1c8) (Java: 1.19.3, Bedrock: 1.19.20 - 1.19.50)
Minecraft: Bedrock Edition Device/Version
ipad 1.19.50
Additional Context
No response