## Successfull full packet flow
This describes the flow of packets and payloads between a client a server that completely implement the protocol. Examples would be NeoForge and Fabric.
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends an empty register packet.
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The servers initial register packet is ignored.
note over Client: The client answers with all known payload ids.
Client -> Server: minecraft:register
note over Client: The versions packet contains a string version per payload id.
Client -> Server: c:version
note over Client: The requirements packet contains a boolean required indicator per payload id.
Client -> Server: c:required
Client -> Server: pong
note over Server: The server processes the clients payload ids.
note over Server: The server answers with all accepted payloads.
Server -> Client: minecraft:register
note over Server: The server answers with a string version per payload id.
Server -> Client: c:version
note over Server: The server answers with a boolean required indicator per payload id.
Server -> Client: c:required
loop Configuration tasks run
Server -> Client: mod_id:do_something
Client -> Server: mod_id:did_something
end
note over Server: The server sends an unregister payload with all known payload ids
Server -> Client: minecraft:unregister
end
group Phase: Play
note over Server: The server sends an empty register packet.
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The servers initial register packet is ignored.
note over Client: The client answers with all known payload ids.
Client -> Server: minecraft:register
note over Client: The versions packet contains a string version per payload id.
Client -> Server: c:version
note over Client: The requirements packet contains a boolean required indicator per payload id.
Client -> Server: c:required
Client -> Server: pong
note over Server: The server processes the clients payload ids.
note over Server: The server answers with all accepted payloads.
Server -> Client: minecraft:register
note over Server: The server answers with a string version per payload id.
Server -> Client: c:version
note over Server: The server answers with a boolean required indicator per payload id.
Server -> Client: c:required
end
@enduml
```
## Sucessfull minimal packet flow
In the case a server or proxy only speaks a "legacy"-flow then the client will not receive the "c" namespaced payloads, and the minecraft:register payloads will need to be differently processed.
Given that we now do not have a way to differentiate between the phases, from a server side perspective (the old protocol simply did not allow it), we will need to assume that all known payloads are common.
This means that the client will need to for example assume that the initial minecraft:register from the server are the payload ids the server supports:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends a filled minecraft:register payload
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The client answers with the payload ids it knows and that are a subset of the servers payload ids
Client -> Server: minecraft:register
Client -> Server: pong
loop Configuration tasks run
Server -> Client: mod_id:do_something
Client -> Server: mod_id:did_something
end
end
group Phase: Play
Server -> Client: Normal start of play phase
end
@enduml
```
This variant of the protocol has significant brawbacks, there is for example no version information available and the sides do not know whether or not a payload is optional. However, it is compatible with even the oldest known protocol variations.
## Negotiation failure full packet flow
Given that there might be situations where the client and the server can not agree to a common set of payloads and their versions, the case will arrise that the connection can not be setup based on this situation.
### Configuration phase
If this happens in the configuration phase negotiation the packet flow will look as follows:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends an empty register packet.
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The servers initial register packet is ignored.
note over Client: The client answers with all known payload ids.
Client -> Server: minecraft:register
note over Client: The versions packet contains a string version per payload id.
Client -> Server: c:version
note over Client: The requirements packet contains a boolean required indicator per payload id.
Client -> Server: c:required
Client -> Server: pong
note over Server: The server processes the clients payload ids, and determines an incompatible setup
Server -> Client: c:failure
Server -> Client: disconnect
end
@enduml
```
There is another alternative route: If the server disregards the clients wishes when it comes to the versioning and compatibility of the channels, then the client is free to disconnect as soon as they realise it. For example when the initial information about the negotiated channels arrives:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends an empty register packet.
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The servers initial register packet is ignored.
note over Client: The client answers with all known payload ids.
Client -> Server: minecraft:register
note over Client: The versions packet contains a string version per payload id.
Client -> Server: c:version
note over Client: The requirements packet contains a boolean required indicator per payload id.
Client -> Server: c:required
Client -> Server: pong
note over Server: The server processes the clients payload ids.
note over Server: The server answers with all accepted payloads.
Server -> Client: minecraft:register
note over Server: The server answers with a string version per payload id.
Server -> Client: c:version
note over Server: The server answers with a boolean required indicator per payload id.
Server -> Client: c:required
note over Client: The client realised that the agreed upon payloads are incompatible with its setup,\n and that the server violated the protocol.
Client -> Server: disconnect
end
@enduml
```
Next to the client detecting that the server used incompatible logic for determining the payload compatibility the client is also free to disconnect at any time if it receives an invalid payload which was not agreed upon, either by this protocol directly, or via the negotiation:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends an empty register packet.
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The servers initial register packet is ignored.
note over Client: The client answers with all known payload ids.
Client -> Server: minecraft:register
note over Client: The versions packet contains a string version per payload id.
Client -> Server: c:version
note over Client: The requirements packet contains a boolean required indicator per payload id.
Client -> Server: c:required
Client -> Server: pong
note over Server: The server processes the clients payload ids.
note over Server: The server answers with all accepted payloads.
Server -> Client: minecraft:register
note over Server: The server answers with a string version per payload id.
Server -> Client: c:version
note over Server: The server answers with a boolean required indicator per payload id.
Server -> Client: c:required
loop Configuration tasks run
note over Server: The server sends an invalid payload
Server -> Client: angry_mod:invalid_payload
note over Client: The client detects the invalid payload
Client -> Server: disconnect
end
end
```
### Play phase
The play phase flows would look similar as the configuration phase flows above.
### When using the minimal payload flow
If the minimal payload flow is in effect, then there the only thing to agree or disagree on is the availability of all payload ids.
In this case if a client does not have all the payload ids of the server the flow would look like follows:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends a filled minecraft:register payload
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The client detects that its payload ids are incompatible with the servers list and disconnects.
Client -> Server: disconnect
@enduml
```
## A vanilla client connects to a modded server
In the case that a vanilla client connects to a modded server, this can be detected by monitoring for the responses to the relevant minecraft:register payloads:
```plantuml
@startuml
participant "Vanilla Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends a filled minecraft:register payload
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The client completly ignores the minecraft:register payload and only responds to the "ping" packet
Client -> Server: pong
@enduml
```
Now the server knows that the client does not support any modded protocol negotiation.
Once this state of the connection has been determined, the server can check if it has any required protocol available.
If so he will disconnect the client:
```plantuml
@startuml
participant "Vanilla Client" as Client
participant "Modded Server" as Server
group Phase: configuration
note over Server: The server sends a filled minecraft:register payload
Server -> Client: minecraft:register
Server -> Client: ping
note over Client: The client completly ignores the minecraft:register payload and only responds to the "ping" packet
Client -> Server: pong
note over Server: Server determines that required modded payloads are needed and disconnects the client
Server -> Client: disconnect
@enduml
```
## A modded client connects to a vanilla server
A vanilla server will never send the minecraft:register payload, and just starts the configuration phase.
This can be used to detect that the modded client is connected to a vanilla server.
Once this determination is made, the vanilla client can determine if it has any required payloads that are now not available:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Vanilla Server" as Server
group Phase: configuration
note over Server: The server immediatly starts with the brand payload (which is the first payload send during configuration)
Server -> Client: minecraft:brand
note over Client: Client detects the vanilla connection and determines elligibility. If compatible will continue to process incoming packets.
Server -> Client: Registry packets
Client -> Server: Acknowledgement packets
loop Configuration tasks run
Server -> Client: mod_id:do_something
Client -> Server: mod_id:did_something
end
@enduml
```
If this client determines that it has required payloads the disconnect flow will look as follows:
```plantuml
@startuml
participant "Modded Client" as Client
participant "Vanilla Server" as Server
group Phase: configuration
note over Server: The server immediatly starts with the brand payload (which is the first payload send during configuration)
Server -> Client: minecraft:brand
note over Client: Client detects the vanilla connection and determines that it is not compatible, then disconnects.
Client -> Server: disconnect
end
@enduml
```