# MLAPI Protocol
#### NOTE
_This protocol specification is TEMPORARY, it's due to change and is just here to give you an aproximate idea of how the protocol works_

The MLAPI protocol is layered. The layers can be seen below.

The first layer is the UDP IP layer. Ontop of the UDP layer, the Unity Network Transport layer is built. And just after that, the MLAPI's protocol starts to appear. The MLAPI has two protocol stages. The first stage is the generic MLAPI message protocol. This is the protocol all messages use that is sent by the user or the MLAPI library.

The structure can be seen below, note that all messages use little endian format.

## MLAPI Generic Message Format
The first two bytes define what message type the message is. This message type is represented as a unsigned int16. The first 32 values are reserved for MLAPI messages. As of version 0.1.7, 10 messages are used. The rest of the message types are reserved for use by the user. That means the user can define ((2^16)-32)=65504  different messageTypes.

The next byte defines if the message is "targeted", see the targeted section on the wiki for more information. The byte is treated as a bool.

**If** the message is targeted (the previous byte was 1)

The next 4 bytes define the target networkId, a unsigned int32.

The next 2 bytes define the networkBehaviour orderId from the root networkObject root. That is, the first networkBehaviour under the networkObject we target (defined by previous 4 bytes) would be a 0, the second one would be a 1 and so on.

**Endif**

The next byte represents wheter or nor the message is a passthrough message, see the passthrough section on the wiki for more information. If the byte is 1, it's true, if it's 0 it's false.

**If** the message is a passthrough message (the previous byte was 1)

The next 4 bytes is a unsigned int32 specifying the clientId this message targted at.

**Endif**

The next two bytes is a unsigned int16 representing the size of the message payload (next field). If the channel this message is sent on is an encrypted channel, this will be the size of the encrypted payload.

The last field is the message payload. It has the size specified in the previous field. This is where the next layer sits. This is the messageData. If it's a user messageType, this is the data you send with your message. Otherwise, see the next section for the MLAPI internal message formats


## MLAPI Internal Messages

### MLAPI_CONNECTION_REQUEST (MessageType 0)
This message type is sent Client to Server. It's purpose is to ask the Server to join by providing information that help the server decide. This is the first message of the MLAPI Handshake

The first 32 bytes is a SHA256 hash of certain fields in the NetworkConfig.

**If** encryption is turned on

The next two bytes represents a unsigned int16 specifying the size of the public diffie hellman key.

The next bytes has the size specified above and contains the diffie hellman public key of the client.

**Endif**

**If** conectionApproval is turned on

The next two bytes represents a unsigned int16 specifying the size of the connectionData.

The next bytes has the size specified above and contains the connectionData.

**Endif**

### MLAPI_CONNECTION_APPROVED (MessageType 1)
This message is sent Server to Client, it's purpose is to notify Client's that their request has been approved and they are now fully joined. This is the last handshake message. (The request being MessageType 0)

The first two bytes represents a unsigned int32 containing the clientId the server has assigned to the recepient.

**If** scene management is enabled

The next 4 bytes represents a unsigned int32 containing the sceneIndex the server is currently using.

**Endif**

**If** encryption is enabled

The next two bytes represents a unsigned int16 specifying the size of the next field.

The next bytes have the size of the previous field and represents the diffie hellman public key.

**If** sign keyexchange is enabled

The next two bytes represents a unsigned int16 specifying the size of the next field.

The next bytes have the size of the previous field and contains a RSA signature of a SHA512 hash of the diffie hellman public key.

**Endif**

**Endif**

The next 4 bytes represents a single precision floating point value containing the current networkTime.

The next 4 bytes represents a signed int32 and contains a network timestamp generated by the NetworkTransport.

The next 4 bytes represents a signed int32 and contains the number of connected clients.

The next (4 * previousField) bytes is a sequence of unsigned int32 containing the clientId of a client.

**If** handle object spawning is turned on

The next 4 bytes represents a signed int32 containing the amount of networkedObjects is spawned.

The next (39 * previousField) represents information about each networkedObject. That is, each NetworkedObject has 39 bytes sent about it. A NetworkedField structure looks like this:

First byte specifies if the object is a playerObject. If the byte is 1, it's true, if it's 0, it's false

The next 4 bytes is a unsigned int32 containing the networkId of the object

The next 4 bytes is a unsigned int32 containing the ownerId of the object

The next 4 bytes is a signed int32 containing the networkedPrefabId to create the object from

The next byte is a boolean specifying if the object is active in the hierarchy

The next byte is a boolean specifying if the object is a sceneObject

The next 4 bytes is a single precision floating point value containing the x position of the object

The next 4 bytes is a single precision floating point value containing the y position of the object

The next 4 bytes is a single precision floating point value containing the z position of the object

The next 4 bytes is a single precision floating point value containing the x rotation of the object

The next 4 bytes is a single precision floating point value containing the y rotation of the object

The next 4 bytes is a single precision floating point value containing the z rotation of the object

**Endif**

### MLAPI_ADD_OBJECT (MessageType 2)
Sent server to client

**If** handle object spawning

The first byte is a boolean, represents if it's a player object or not

The next 4 bytes is a unsigned int32 representing the networkId

The next 4 bytes is a unsigned int32 representing the ownerId

The next 4 bytes is signed int32 represents the prefabId

The next byte is a bool representing if it's a sceneObject

The next 4 bytes is a single precision floating point value containing the x position of the object

The next 4 bytes is a single precision floating point value containing the y position of the object

The next 4 bytes is a single precision floating point value containing the z position of the object

The next 4 bytes is a single precision floating point value containing the x rotation of the object

The next 4 bytes is a single precision floating point value containing the y rotation of the object

The next 4 bytes is a single precision floating point value containing the z rotation of the object

**Else**

The first 4 bytes represents a unsigned int32 containing the ownerId

**Endif**

### MLAPI_CLIENT_DISCONNECT (MessageType 3)
Sent server to client

The first 4 bytes is a unsigned int32 containing the clientId

### MLAPI_DESTROY_OBJECT (MessageType 4)
Server to client

The first 4 bytes is a unsigned int32 containing the netId

### MLAPI_SWITCH_SCENE (MessageType 5)
Server to client

The first 4 bytes is a unsigned int32 containing the sceneId


### MLAPI_SPAWN_POOL_OBJECT (MessageType 6)
Server to client

The first 4 bytes is a unsigned int32 containing the netId

The next 4 bytes is a single precision floating point value containing the x position of the object

The next 4 bytes is a single precision floating point value containing the y position of the object

The next 4 bytes is a single precision floating point value containing the z position of the object

The next 4 bytes is a single precision floating point value containing the x rotation of the object

The next 4 bytes is a single precision floating point value containing the y rotation of the object

The next 4 bytes is a single precision floating point value containing the z rotation of the object

### MLAPI_DESTROY_POOL_OBJECT (MessageType 7)
Server to client

The first 4 bytes is a unsigned int32 containing the netId

### MLAPI_CHANGE_OWNER (MessageType 8)
Server to client

The first 4 bytes is a unsigned int32 containing the netId

The first 4 bytes is a unsigned int32 containing the ownerClientId

### MLAPI_SYNC_VAR_UPDATE (MessageType 9)
Server to client

The first byte represents the amount of dirty fields

The next 4 bytes is a unsigned int32 containing the netId

The next 2 bytes is a unsigned int16 containing the order of the netBehaviour

//HERE IS THE SYNCVAR DATA. NOTHING TO OPTIMIZE

### MLAPI_ADD_OBJECTS (MessageType 10)
Server to client

Same as ADD_OBJECT, but contains two bytes (unsigned int16 specifying the amount of objects, then repeated ADD_OBJECT patterns)
