-
-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split incoming/outgoing packet registry, transition protocol states correctly #841
Conversation
PR is ready for review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, especially like the cleanup in the listeners
protocol/src/main/java/org/geysermc/mcprotocollib/network/packet/Packet.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpFlowControlHandler.java
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java
Outdated
Show resolved
Hide resolved
// The developer who sends ClientboundStartConfigurationPacket needs to setOutboundState to CONFIGURATION | ||
// after sending the packet. We can't do it in this class because it needs to be a method call right after it was sent. | ||
// Using nettys event loop to change outgoing state may cause differences to vanilla. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we not check for ClientboundStartConfigurationPacket
in packetSent
, and setOutboundState to CONFIGURATION there? packetSent
should be invoked more or less right after the onSent
callback would be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have the developers explicitly switch them like in vanilla. The entire onSent thing is made because of that reason. Stuff in packetSent may be not be handled immediately because packets sometimes get handled on the event loop. However onSent is guaranteed to be handled inside the netty pipeline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClientboundStartConfigurationPacket is not isPriority
therefore it gets handled on the event loop
so if you
send(ClientboundStartConfigurationPacket)
and
send(SomeConfigurationPacket)
as a developer right after each other, it'll error because the event loop is having a race condition with the netty pipeline
One other fix would be setting ClientboundStartConfigurationPacket as isPriority, but I don't wanna touch that with this PR
onSent allows the dev to change the state the next packets gets decoded with immediately without the chance of race conditions because of off-pipeline processing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry if I don't understand.
Stuff in packetSent may be not be handled immediately because packets sometimes get handled on the event loop. However onSent is guaranteed to be handled inside the netty pipeline.
I read them as being called right after eachother? https://github.com/AlexProgrammerDE/MCProtocolLib/blob/2b310d2618f23127640a85194623126b1eef594b/protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpSession.java#L271-L275
Also, isPriority doesn't seem to apply to outbound packets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah you're right. I was thinking too much from the clients perspective that all packets are in the event loop. Would still be weird though to add back packetSent...
It makes it harder to compare logic with vanilla.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does have the distinction now that any packets handled by ServerListener in the packetSent event are packets that have been sent by the library user, not internal MCPL. I think its worth it to not introduce state switching to the library user for a single case (if i understand correctly)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now not even possible anymore since explicit flushes after the writeAndFlush are needed due to race conditions. The code doesn't use onSent anymore for state switching. Developers need to manually switch state after sending the packet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would still be weird though to add back packetSent...
It makes it harder to compare logic with vanilla.
Minecraft is also the maintainer AND user of its network code—I think it is worth it here for the sake of ease of use.
Minecraft has a method for sending ClientboundStartConfigurationPacket and switching outbound protocol, but I'm not sure this project's structure would facilitate something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate?
What I'm saying is that the calling thread for the switchOutbound matters. Always forcing it to be inside netty threads could lead to deadlocks if the event loop is used for the inbound processing.
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCodec.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java
Show resolved
Hide resolved
…ion.java Co-authored-by: chris <[email protected]>
…ecraftProtocol.java Co-authored-by: chris <[email protected]>
…ecraftProtocol.java Co-authored-by: chris <[email protected]>
This replicates the same approach Mojang uses in their networking code.
Race conditions and weird disconnects are fixed. This PR can be merged. |
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpServer.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpPacketCodec.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/DropPacketFilter.java
Outdated
Show resolved
Hide resolved
…TcpServer.java Co-authored-by: chris <[email protected]>
// The developer who sends ClientboundStartConfigurationPacket needs to setOutboundState to CONFIGURATION | ||
// after sending the packet. We can't do it in this class because it needs to be a method call right after it was sent. | ||
// Using nettys event loop to change outgoing state may cause differences to vanilla. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would still be weird though to add back packetSent...
It makes it harder to compare logic with vanilla.
Minecraft is also the maintainer AND user of its network code—I think it is worth it here for the sake of ease of use.
Minecraft has a method for sending ClientboundStartConfigurationPacket and switching outbound protocol, but I'm not sure this project's structure would facilitate something like that?
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java
Outdated
Show resolved
Hide resolved
# Conflicts: # protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ClientListener.java # protocol/src/main/java/org/geysermc/mcprotocollib/protocol/ServerListener.java
protocol/src/main/java/org/geysermc/mcprotocollib/protocol/MinecraftProtocol.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/tcp/TcpClientSession.java
Outdated
Show resolved
Hide resolved
protocol/src/main/java/org/geysermc/mcprotocollib/network/Session.java
Outdated
Show resolved
Hide resolved
As discussed on discord, being able to disable/suppress the packet en/decoding logging while in debug mode using e.g. markers as flags would be ideal. |
Should be able to be reviewed now. Added the markers. |
These changes are necessary to avoid race-conditions in the code and to prepare the codebase for ViaVersion support.