mc_protocol v0.0.1 McProtocol.Handler behaviour

Basic component for the connection state machine.

This behaviour is what makes McProtocol flexible. To work with the standard acceptor, you need to implement the behaviour defined in this module.

Interaction

A handler has two ways to interact with the connection it’s associated with, synchronous, and asynchronous.

Synchronous interaction is named a transition (it transitions the connection state machine into a new state). Transitions can do things like set protocol encryption, send packets, raw data, or transition to a new protocol state. It allows you to control the precise order of operations.

(Most of this is not done yet) Asynchronous interaction is done by messaging. Any process can interact with any connection, as long as it has the pid and state cookie. Because the exact order of operations can not be controlled, things like setting encryption or compression is not possible.

Handler stacks

The minecraft protocol has some common, easily reusable stages, like handshake, status or login. Handlers combined with handler stacks makes it easy to separate these things into small, reusable modules. When designing something like a custom server, you could define a parent_handler/0 function that returns McProtocol.Handler.Login. The acceptor would then traverse upwards, grabbing the parent handler of each parent until it hits :connect, in this case McProtocol.Handler.Handshake. It would start there, go back up the chain until control is given to your handler.

Summary

Types

handler :: module
handler_state :: term
transition ::
  {:set_encryption, %McProtocol.Crypto.Transport.CryptData{ivec: term, key: term}} |
  {:set_compression, integer} |
  {:send_packet, McProtocol.Packet.t} |
  {:send_data, iodata} |
  {:next, protocol_state} |
  {:next, handler, protocol_state}

Functions

handler_stack(handler)

Callbacks

handle(binary, handler_state)

Specs

handle(binary, handler_state) :: {[transition], handler_state}
initial_state(protocol_state)

Specs

initial_state(protocol_state) :: handler_state
parent_handler()

Specs

parent_handler :: handler | :connect | nil