Difference between revisions of "Pocket Edition Protocol Documentation"
(Add uint24le data type) |
(Add a bunch of RakNet-level packets) |
||
Line 2: | Line 2: | ||
Currently, the game's default port is 19132. It is recommended to use this when possible because processes such as server discovering will not work otherwise. | Currently, the game's default port is 19132. It is recommended to use this when possible because processes such as server discovering will not work otherwise. | ||
+ | |||
+ | Some of this work was sponsored by CubeCraft. Big thanks to them. | ||
== Data Types == | == Data Types == | ||
Line 47: | Line 49: | ||
| class="col2" | N/A | | class="col2" | N/A | ||
| class="col3" | Prefixed by a short containing the length of the string in characters. It appears that only the following ASCII characters can be displayed: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ | | class="col3" | Prefixed by a short containing the length of the string in characters. It appears that only the following ASCII characters can be displayed: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ | ||
+ | |- class="row8" | ||
+ | ! class="col0 centeralign" | address | ||
+ | | class="col1 centeralign" | 7 | ||
+ | | class="col2" | N/A | ||
+ | | class="col3" | IP Address and port. First byte is the version (0x04), then come the address bytes and finally an unsigned short for the port. | ||
|} | |} | ||
Line 52: | Line 59: | ||
All packets in Minecraft: Pocket Edition start with their ID, which is an unsigned byte. If you are using a language which does not support unsigned types such as Java, you can do (byte & 0xFF) to get the unsigned version. | All packets in Minecraft: Pocket Edition start with their ID, which is an unsigned byte. If you are using a language which does not support unsigned types such as Java, you can do (byte & 0xFF) to get the unsigned version. | ||
+ | == RakNet protocol == | ||
+ | |||
+ | === Connected Ping === | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x00 | ||
+ | | Time | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Unconnected Ping === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="2"| 0x01, 0x02 | ||
+ | | Time | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | GUID | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | <code>0x02</code> is only replied to if there are open connections to the server. | ||
+ | |||
+ | === Connected Pong === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="2"| 0x03 | ||
+ | | Ping Time | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | Pong Time | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Offline Connection Request 1 === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="3"| 0x05 | ||
+ | | Magic | ||
+ | | MAGIC | ||
+ | | | ||
+ | |- | ||
+ | | Protocol version | ||
+ | | byte | ||
+ | | Currently 7 | ||
+ | |- | ||
+ | | MTU | ||
+ | | mtu-46 zero bytes | ||
+ | | The MTU sent in the response appears to be somewhere around the size of this padding + 46 (28 udp overhead, 1 packet id, 16 magic, 1 protocol version) | ||
+ | |} | ||
+ | |||
+ | The client sends these to the target server with ever decreasing MTU until the server responds. This is used to discover the MTU size for the connection. | ||
+ | |||
+ | === Offline Connection Response 1 === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="3"| 0x06 | ||
+ | | Magic | ||
+ | | MAGIC | ||
+ | | | ||
+ | |- | ||
+ | | Server GUID | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | MTU | ||
+ | | short | ||
+ | | see Offline Connection Request 1 | ||
+ | |} | ||
+ | |||
+ | === Offline Connection Request 2 === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="4"| 0x07 | ||
+ | | Magic | ||
+ | | MAGIC | ||
+ | | | ||
+ | |- | ||
+ | | Server Address | ||
+ | | address | ||
+ | | | ||
+ | |- | ||
+ | | MTU | ||
+ | | short | ||
+ | | | ||
+ | |- | ||
+ | | Client GUID | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Offline Connection Response 2 === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="5"| 0x08 | ||
+ | | Magic | ||
+ | | MAGIC | ||
+ | | | ||
+ | |- | ||
+ | | Server GUID | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | Client Address | ||
+ | | address | ||
+ | | | ||
+ | |- | ||
+ | | MTU | ||
+ | | short | ||
+ | | | ||
+ | |- | ||
+ | | Encryption enabled? | ||
+ | | byte | ||
+ | | 0 for disabled. | ||
+ | |} | ||
+ | |||
+ | === Online Connection Request === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="2"| 0x09 | ||
+ | | GUID | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | Time | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Online Connection Request Accepted === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="5"| 0x10 | ||
+ | | Client address | ||
+ | | address | ||
+ | | | ||
+ | |- | ||
+ | | System index | ||
+ | | short | ||
+ | | Unknown what this does. 0 works as a value. | ||
+ | |- | ||
+ | | Internal IDs | ||
+ | | 10x address | ||
+ | | Unknown what these do. 255.255.255.255:19132 for all of them seems to work, any other address will probably work as well. | ||
+ | |- | ||
+ | | Request time | ||
+ | | long | ||
+ | | | ||
+ | |- | ||
+ | | Time | ||
+ | | long | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Frame Set Packet === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | !colspan="3"| Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | |rowspan="11"| 0x80..0x8d | ||
+ | |colspan="3"| Frame Set index | ||
+ | | uint24le | ||
+ | | | ||
+ | |- | ||
+ | |rowspan="10"| Frames | ||
+ | |colspan="2"| Flags | ||
+ | | byte | ||
+ | | Top 3 bits are reliability type, fourth bit is 1 when the frame is fragmented and part of a compound. | ||
+ | |- | ||
+ | |colspan="2"| Length IN BITS | ||
+ | | short | ||
+ | | Length of the body in bits. | ||
+ | |- | ||
+ | |colspan="2"| Reliable frame index | ||
+ | | uint24le | ||
+ | | only if reliable | ||
+ | |- | ||
+ | |colspan="2"| Sequenced frame index | ||
+ | | uint24le | ||
+ | | only if sequenced | ||
+ | |- | ||
+ | |rowspan="2"| Order | ||
+ | | Ordered frame index | ||
+ | | uint24le | ||
+ | |rowspan="2"| only if ordered | ||
+ | |- | ||
+ | | Order channel | ||
+ | | byte | ||
+ | |- | ||
+ | |rowspan="3"| Fragment | ||
+ | | Compound size | ||
+ | | int | ||
+ | |rowspan="3"| only if fragmented | ||
+ | |- | ||
+ | | Compound ID | ||
+ | | short | ||
+ | |- | ||
+ | | Index | ||
+ | | int | ||
+ | |- | ||
+ | | Body | ||
+ | | ceil(length/8) bytes | ||
+ | |} | ||
+ | |||
+ | The reliability types are as follows: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! style="text-align: center; font-weight: bold;" | ID | ||
+ | ! style="font-weight: bold;" | Name | ||
+ | ! style="text-align: center; font-weight: bold;" | Reliable | ||
+ | ! style="text-align: center; font-weight: bold;" | Ordered | ||
+ | ! style="text-align: center; font-weight: bold;" | Sequenced | ||
+ | |- | ||
+ | | style="text-align: center;" | 0 | ||
+ | | unreliable | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | |- | ||
+ | | style="text-align: center;" | 1 | ||
+ | | unreliable sequenced | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | x | ||
+ | |- | ||
+ | | style="text-align: center;" | 2 | ||
+ | | reliable | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | |- | ||
+ | | style="text-align: center;" | 3 | ||
+ | | reliable ordered | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | | ||
+ | |- | ||
+ | | style="text-align: center;" | 4 | ||
+ | | reliable sequenced | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | x | ||
+ | |- | ||
+ | | style="text-align: center;" | 5 | ||
+ | | unreliable (+ ACK receipt) | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | |- | ||
+ | | style="text-align: center;" | 6 | ||
+ | | reliable (+ ACK receipt) | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | | ||
+ | | style="text-align: center;" | | ||
+ | |- | ||
+ | | style="text-align: center;" | 7 | ||
+ | | reliable ordered (+ ACK receipt) | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | x | ||
+ | | style="text-align: center;" | | ||
+ | |} | ||
+ | |||
+ | Sequenced implies ordered. | ||
+ | |||
+ | === Game Packet === | ||
+ | {| class="wikitable" | ||
+ | ! Packet ID | ||
+ | ! Field Name | ||
+ | ! Field Type | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x8e | ||
+ | | Body | ||
+ | | bytes | ||
+ | | Single packet of the GAME protocol. | ||
+ | |} | ||
+ | |||
+ | === NACK === | ||
+ | {| class="wikitable" | ||
+ | ! style="font-weight: bold;" | Packet ID | ||
+ | ! colspan="3" style="font-weight: bold;" | Field Name | ||
+ | ! style="font-weight: bold;" | Field Type | ||
+ | ! style="font-weight: bold;" | Notes | ||
+ | |- | ||
+ | | 0xa0 | ||
+ | | colspan="3" | Record count | ||
+ | | short | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | rowspan="4" | Record | ||
+ | | colspan="2" | Is Range? | ||
+ | | byte | ||
+ | | 0 for range, 1 for no range | ||
+ | |- | ||
+ | | | ||
+ | | No Range | ||
+ | | Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | rowspan="2" | Range | ||
+ | | Start Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | End Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === ACK === | ||
+ | {| class="wikitable" | ||
+ | ! style="font-weight: bold;" | Packet ID | ||
+ | ! colspan="3" style="font-weight: bold;" | Field Name | ||
+ | ! style="font-weight: bold;" | Field Type | ||
+ | ! style="font-weight: bold;" | Notes | ||
+ | |- | ||
+ | | 0xc0 | ||
+ | | colspan="3" | Record count | ||
+ | | short | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | rowspan="4" | Record | ||
+ | | colspan="2" | Is Range? | ||
+ | | byte | ||
+ | | 0 for range, 1 for no range | ||
+ | |- | ||
+ | | | ||
+ | | No Range | ||
+ | | Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | rowspan="2" | Range | ||
+ | | Start Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |- | ||
+ | | | ||
+ | | End Index | ||
+ | | uint24le | ||
+ | | | ||
+ | |} | ||
== References == | == References == |
Revision as of 20:36, 9 April 2016
This is the (unofficial) protocol documentation for Minecraft Pocket Edition. The protocol currently uses UDP for communication, different from PC (which uses TCP). The usual UDP issues are still here (lost packets, wrong order, etc.), but the protocol solves a few of those problems using special packet encapsulation, based on TCP. The Minecraft: PE client uses RakNet as its networking library. Even though it uses RakNet, you can still write software without the library.
Currently, the game's default port is 19132. It is recommended to use this when possible because processes such as server discovering will not work otherwise.
Some of this work was sponsored by CubeCraft. Big thanks to them.
Contents
- 1 Data Types
- 2 Packet format
- 3 RakNet protocol
- 3.1 Connected Ping
- 3.2 Unconnected Ping
- 3.3 Connected Pong
- 3.4 Offline Connection Request 1
- 3.5 Offline Connection Response 1
- 3.6 Offline Connection Request 2
- 3.7 Offline Connection Response 2
- 3.8 Online Connection Request
- 3.9 Online Connection Request Accepted
- 3.10 Frame Set Packet
- 3.11 Game Packet
- 3.12 NACK
- 3.13 ACK
- 4 References
Data Types
Minecraft packets use different data types to communicate with each other. The documented ones are listed below:
Size | Range | Notes | |
---|---|---|---|
byte | 1 | -128 to 127 |
|
short | 2 | -32768 to 32767 |
|
uint24le | 3 | 0 to 16777216 | Little-Endian 24-bit unsigned integer. Commonly used by RakNet for counters.
|
int | 4 | -2147483648 to 2147483647 |
|
long | 8 |
| |
MAGIC | 16 | 0x00ffff00fefefefefdfdfdfd12345678
|
always those hex bytes, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID |
string | unsigned short + string | N/A | Prefixed by a short containing the length of the string in characters. It appears that only the following ASCII characters can be displayed: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ |
address | 7 | N/A | IP Address and port. First byte is the version (0x04), then come the address bytes and finally an unsigned short for the port. |
Packet format
All packets in Minecraft: Pocket Edition start with their ID, which is an unsigned byte. If you are using a language which does not support unsigned types such as Java, you can do (byte & 0xFF) to get the unsigned version.
RakNet protocol
Connected Ping
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x00 | Time | long |
Unconnected Ping
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x01, 0x02 | Time | long | |
GUID | long |
0x02
is only replied to if there are open connections to the server.
Connected Pong
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x03 | Ping Time | long | |
Pong Time | long |
Offline Connection Request 1
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x05 | Magic | MAGIC | |
Protocol version | byte | Currently 7 | |
MTU | mtu-46 zero bytes | The MTU sent in the response appears to be somewhere around the size of this padding + 46 (28 udp overhead, 1 packet id, 16 magic, 1 protocol version) |
The client sends these to the target server with ever decreasing MTU until the server responds. This is used to discover the MTU size for the connection.
Offline Connection Response 1
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x06 | Magic | MAGIC | |
Server GUID | long | ||
MTU | short | see Offline Connection Request 1 |
Offline Connection Request 2
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x07 | Magic | MAGIC | |
Server Address | address | ||
MTU | short | ||
Client GUID | long |
Offline Connection Response 2
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x08 | Magic | MAGIC | |
Server GUID | long | ||
Client Address | address | ||
MTU | short | ||
Encryption enabled? | byte | 0 for disabled. |
Online Connection Request
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x09 | GUID | long | |
Time | long |
Online Connection Request Accepted
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x10 | Client address | address | |
System index | short | Unknown what this does. 0 works as a value. | |
Internal IDs | 10x address | Unknown what these do. 255.255.255.255:19132 for all of them seems to work, any other address will probably work as well. | |
Request time | long | ||
Time | long |
Frame Set Packet
Packet ID | Field Name | Field Type | Notes | ||
---|---|---|---|---|---|
0x80..0x8d | Frame Set index | uint24le | |||
Frames | Flags | byte | Top 3 bits are reliability type, fourth bit is 1 when the frame is fragmented and part of a compound. | ||
Length IN BITS | short | Length of the body in bits. | |||
Reliable frame index | uint24le | only if reliable | |||
Sequenced frame index | uint24le | only if sequenced | |||
Order | Ordered frame index | uint24le | only if ordered | ||
Order channel | byte | ||||
Fragment | Compound size | int | only if fragmented | ||
Compound ID | short | ||||
Index | int | ||||
Body | ceil(length/8) bytes |
The reliability types are as follows:
ID | Name | Reliable | Ordered | Sequenced |
---|---|---|---|---|
0 | unreliable | |||
1 | unreliable sequenced | x | x | |
2 | reliable | x | ||
3 | reliable ordered | x | x | |
4 | reliable sequenced | x | x | x |
5 | unreliable (+ ACK receipt) | |||
6 | reliable (+ ACK receipt) | x | ||
7 | reliable ordered (+ ACK receipt) | x | x |
Sequenced implies ordered.
Game Packet
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x8e | Body | bytes | Single packet of the GAME protocol. |
NACK
Packet ID | Field Name | Field Type | Notes | ||
---|---|---|---|---|---|
0xa0 | Record count | short | |||
Record | Is Range? | byte | 0 for range, 1 for no range | ||
No Range | Index | uint24le | |||
Range | Start Index | uint24le | |||
End Index | uint24le |
ACK
Packet ID | Field Name | Field Type | Notes | ||
---|---|---|---|---|---|
0xc0 | Record count | short | |||
Record | Is Range? | byte | 0 for range, 1 for no range | ||
No Range | Index | uint24le | |||
Range | Start Index | uint24le | |||
End Index | uint24le |
References
RakNet datagram and message header information: http://jenkinssoftware.com/raknet/manual/systemoverview.html
The latest version of the protocol is not fully documented yet, but all of the packets can be found in the Dragonet server code https://github.com/DragonetMC/Dragonet/tree/master/src/main/java/org/dragonet/net/packet Protocol Version: 23 (MCPE 0.11.0b6)
The older protocol specification(ver <= 0.10.x): There is also an automatically generated specification of many of the packages can be found in the MiNET server code https://github.com/NiclasOlofsson/MiNET/blob/master/src/MiNET/MiNET/Net/MCPE%20Protocol%20Documentation.md
The MiNET wiki also contain development notes around some functionality https://github.com/NiclasOlofsson/MiNET/wiki These will be migrated to this wiki in due time.