# Networking rework
## Vanilla packet flow
### Status
```sequence
Client->Server: ClientIntentionPacket(protocolVersion, hostName, port, intention = STATUS)
Note over Client,Server: Start Status phase
Client->Server: ServerboundStatusRequestPacket
Server->Client: ClientboundStatusResponsePacket(status)
```
### Ping
```sequence
Client->Server: ClientIntentionPacket(protocolVersion, hostName, port, intention = STATUS)
Note over Client,Server: Start Status phase
Client->Server: ServerboundPingRequestPacket(time)
Server->Client: ClientboundPongResponsePacket(time)
```
### Login
```sequence
Client->Server: ClientIntentionPacket(protocolVersion, hostName, port, intention = LOGIN)
Note over Client,Server: Start Login phase
Client->Server: ServerboundHelloPacket(name, profileId)
Note over Server: Set state to KEY
Server->Client: ClientboundHelloPacket(serverId, publicKey, challenge)
Note over Client: Set state to AUTHORIZING
Note over Client: Set state to ENCRYPTING
Client->Server: ServerboundKeyPacket(keybytes, encryptedChallenge)
Note over Server: Set state to AUTHENTICATING
Note over Server: Set state to VERIFYING
Server->Client: ClientboundLoginCompressionPacket(compressionThreshold)
Note over Server: Set state to WAITING_FOR_DUPE_DISCONNECT
Note over Server: Set state to PROTOCOL_SWITCHING
Server->Client: ClientboundGameProfilePacket(gameProfile)
Note over Client: Set state to JOINING
Client->Server: ServerboundLoginAcknowledgedPacket
Note over Server: Set state to ACCEPTED
Note over Client,Server: Start Configuration phase
Client->Server: ServerboundCustomPayloadPacket(minecraft:brand)
Client->Server: ServerboundClientInformationPacket(information)
Server->Client: ClientboundCustomPayloadPacket(minecraft:brand)
Server->Client: ClientboundUpdateEnabledFeaturesPacket(features)
Server->Client: ClientboundRegistryDataPacket(registries)
Server->Client: ClientboundUpdateTagsPacket(tags)
Server-->Client: ClientboundResourcePackPacket(url, hash, required, prompt)
Server->Client: ClientboundFinishConfigurationPacket
Note over Client,Server: Start Play phase
```
## New implementation
- Underlying system relies solely on `CustomQueryPacket` and `CustomPayloadPacket`
- If a mod registers at least one of these, and does not mark it as optional, then the server is considered not compatible with vanilla
- An event is fired from the mod bus to collect a mods packets and their listeners, it is up to a mod to ensure that these are compatible with each other.
### Server status pinging
- ServerStatus now holds only an indicator if the server the client is requesting status of is modded or not.
- A vanilla client ignores this information because it is encoded in a not read part of the JSON structure
- A modded client can then send additional packets to the modded server, requesting additional information, like the mods list, or the custom packet list.
#### Modded Client <-> Modded Server connection
```sequence
Client->Server: ServerboundStatusRequestPacket
Server->Client: ClientboundStatusResponsePacket(serverStatus.isModdedConnection = true)
Client->Server: ServerboundCustomPayloadPacket(minecraft:register, customPacketIds)
Server->Client: ClientboundCustomPayloadPacket(minecraft:network, acceptedPacketsConfigPhase, acceptedPacketsPlayPhase)
```
The connection is basically upgraded from one that does not support custom packet payloads to one that does support them, because both sides know that they are modded.
#### Vanilla Client <-> Modded Server connection
```sequence
Client->Server: ServerboundStatusRequestPacket
Server->Client: ClientboundStatusResponsePacket(serverStatus.isModdedConnection = true)
```
The vanilla client ignores the additional field on the JSON that is send for the server status, and the server notices that no additional packets get returned and gets an indication that the client is unsupported.
#### Modded Client <-> Vanilla Server connection
```sequence
Client->Server: ServerboundStatusRequestPacket
Server->Client: ClientboundStatusResponsePacket
```
The client detects that the isModdedConnection field is missing, and does not try to upgrade the connection but will locally validate that his network setup works with a vanilla connection.
### Configuration phase
- An event is fired during the configuration phase, that allows mods to send additional packets to sync custom configuration data
- This is implemented via the custom task queue that exists in vanilla
```sequence
Client->Server: ClientIntentionPacket(protocolVersion, hostName, port, intention = LOGIN)
Note over Client,Server: Start Login phase
Client->Server: ServerboundHelloPacket(name, profileId)
Note over Server: Set state to KEY
Server->Client: ClientboundHelloPacket(serverId, publicKey, challenge)
Note over Client: Set state to AUTHORIZING
Note over Client: Set state to ENCRYPTING
Client->Server: ServerboundKeyPacket(keybytes, encryptedChallenge)
Note over Server: Set state to AUTHENTICATING
Note over Server: Set state to VERIFYING
Server->Client: ClientboundLoginCompressionPacket(compressionThreshold)
Note over Server: Set state to WAITING_FOR_DUPE_DISCONNECT
Note over Server: Set state to PROTOCOL_SWITCHING
Server->Client: ClientboundGameProfilePacket(gameProfile)
Note over Client: Set state to JOINING
Client->Server: ServerboundLoginAcknowledgedPacket
Note over Server: Set state to ACCEPTED
Note over Client,Server: Start Configuration phase
Client->Server: ServerboundCustomPayloadPacket(minecraft:brand)
Client->Server: ServerboundClientInformationPacket(information)
Note over Client,Server: Start of Configuration Phase execution
Server->Client: ClientboundCustomPayloadPacket(minecraft:register)
Server->Client: ClientboundPingPacket(0)
Client->Server: ServerboundCustomPayloadPacket(minecraft:register, customPacketIds)
Client->Server: ServerboundPongPacket(0)
Server->Client: ClientboundCustomPayloadPacket(minecraft:network, acceptedPacketsConfigPhase, acceptedPacketsPlayPhase)
Note over Server: Actual start of configuration task processing
Server->Client: ClientboundCustomPayloadPacket(minecraft:brand)
Server->Client: ClientboundUpdateEnabledFeaturesPacket(features)
Server->Client: ClientboundRegistryDataPacket(registries)
Server->Client: ClientboundUpdateTagsPacket(tags)
Server-->Client: ClientboundResourcePackPacket(url, hash, required, prompt)
Note over Client,Server: Mod configuration tasks here
Server->Client: ClientboundFinishConfigurationPacket
Note over Client,Server: Start Play phase
```