Difference between revisions of "Pocket Minecraft Protocol"

From wiki.vg
Jump to navigation Jump to search
m (Real PE packets warning)
m (Fix UpdateBlockPacket table)
 
(138 intermediate revisions by 16 users not shown)
Line 1: Line 1:
 +
{{Box
 +
  |BORDER = #9999FF
 +
  |BACKGROUND = #99CCFF
 +
  |WIDTH = 100%
 +
  |ICON =
 +
  |HEADING = Heads up!
 +
  |CONTENT = This is outdated information for Minecraft Pocket Edition.'''. For the latest Bedrock Edition protocol documentation see [[Bedrock Protocol]].
 +
}}
 +
 
Unlike the Minecraft protocol, this protocol uses UDP with (so far observed, at least) one message per packet. This makes the protocol easier to work with when it comes to packet serialization, and might offer latency improvements, but will inevitably have the usual UDP issues (packets lost, truncated, duplicated, out-of-order, etc.).
 
Unlike the Minecraft protocol, this protocol uses UDP with (so far observed, at least) one message per packet. This makes the protocol easier to work with when it comes to packet serialization, and might offer latency improvements, but will inevitably have the usual UDP issues (packets lost, truncated, duplicated, out-of-order, etc.).
  
Old servers listen on UDP port 19132.  
+
'''As of 0.9.0, clients appear to search for servers on only port 19132.'''
As of the survival update, the port is the same
+
 
 
Clients don't pick any specific port to listen on.
 
Clients don't pick any specific port to listen on.
  
Please note that even where packet field names are written in this page, these are still largely hypothetical and could well be incorrect guesses.
+
 
 +
Please note that even where packet field names are written in this page, these are still largely hypothetical and could well be incorrect guesses. Some packets are fixed to the RakNet protocol, and will be marked as "RakNet Packet", which means that these packets will not change on future versions.
  
 
It has been determined that PM uses RakNet for its networking library, [http://www.jenkinssoftware.com/raknet/manual/networkmessages.html some documentation that seems relevant].
 
It has been determined that PM uses RakNet for its networking library, [http://www.jenkinssoftware.com/raknet/manual/networkmessages.html some documentation that seems relevant].
 +
 +
 +
The [[Pocket_Editon_Login|login sequence]] is not covered by this page.
  
  
Line 46: Line 59:
 
| class="col1 centeralign" | 16
 
| class="col1 centeralign" | 16
 
| class="col2" | <code>0x00ffff00fefefefefdfdfdfd12345678</code>
 
| class="col2" | <code>0x00ffff00fefefefefdfdfdfd12345678</code>
| class="col3" | always hex bytes <code>0x00ffff00fefefefefdfdfdfd12345678</code>, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID
+
| class="col3" | always those hex bytes, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID
 
|- class="row6"
 
|- class="row6"
 
! class="col0 centeralign" | string
 
! class="col0 centeralign" | string
| class="col1 centeralign" | 1
+
| class="col1 centeralign" | = 1
 
| 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{|}~
 
|}
 
|}
  
== Packets ==
+
== Login Packets ==
  
 
All packets start with a single byte that identifies the packet type, the rest of the packet follows it.
 
All packets start with a single byte that identifies the packet type, the rest of the packet follows it.
 +
Please note that packets 0x09 through 0x13 are not documented (yet).
 +
 +
{{anchor|0x01}}
 +
=== ID_CONNECTED_PING_OPEN_CONNECTIONS (0x01) ===
 +
 +
''Client to Broadcast''
 +
 +
 +
'''RakNet Packet'''
 +
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="2" | 0x01
 +
| class="col1 centeralign" | Ping ID
 +
| class="col2 centeralign" | int64
 +
| class="col3 centeralign" | <code>0x00000000003c6d0d</code>
 +
| class="col4" | Time since start in Milliseconds
 +
|- class="row2"
 +
| class="col0 centeralign" | MAGIC
 +
| class="col1 centeralign" | MAGIC
 +
| class="col2 centeralign" |
 +
| class="col3" |
 +
|- class="row3"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 25 Bytes
 +
|}
 +
 +
Clients start out by sending this packet to the IP broadcast address on port 19132 repeatedly (approx once per second) when joining a server was chosen on the main screen, and stops when the user selects a server (or leaves the screen). The ping ID from the client increases over time, and appears to be the number of milliseconds since the client program was started (might be used to measure server response latency).
  
 
{{anchor|0x02}}
 
{{anchor|0x02}}
Line 62: Line 109:
  
 
''Client to Broadcast''
 
''Client to Broadcast''
 +
 +
'''NOTE: THIS PACKET APPEARS TO BE UNUSED. Use a 0x01 packet instead'''
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 71: Line 122:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="3" | 0x02
+
| class="col0 centeralign" rowspan="2" | 0x02
 
| class="col1 centeralign" | Ping ID
 
| class="col1 centeralign" | Ping ID
 
| class="col2 centeralign" | int64
 
| class="col2 centeralign" | int64
Line 86: Line 137:
 
|}
 
|}
  
Clients start out by sending this packet to the IP broadcast address on port 19132 repeatedly (approx once per second) when joining a server was chosen on the main screen, and stops when the user selects a server (or leaves the screen). The ping ID from the client increases over time, and appears to be the number of milliseconds since the client program was started (might be used to measure server response latency).
+
Same as [[#0x01|ID_CONNECTED_PING_OPEN_CONNECTIONS (0x01)]], but with the Packet ID changed.
  
 +
{{anchor|0x05}}
  
{{anchor|0x05}}
 
 
=== ID_OPEN_CONNECTION_REQUEST_1 (0x05) ===
 
=== ID_OPEN_CONNECTION_REQUEST_1 (0x05) ===
  
 
''Client to Server''
 
''Client to Server''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 102: Line 156:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="4" | 0x05
+
| class="col0 centeralign" rowspan="3" | 0x05
 
| class="col1 centeralign" | MAGIC
 
| class="col1 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
Line 108: Line 162:
 
| class="col4" |  
 
| class="col4" |  
 
|- class="row2"
 
|- class="row2"
| class="col0 centeralign" | Protocol Version
+
| class="col0 centeralign" | RakNet Protocol Version
 
| class="col1 centeralign" | byte
 
| class="col1 centeralign" | byte
 
| class="col2 centeralign" | <code>5</code>
 
| class="col2 centeralign" | <code>5</code>
| class="col3" | Currently 5
+
| class="col3" | Check the Data Packet section for the current version
 
|- class="row2"
 
|- class="row2"
 
| class="col0 centeralign" | Null Payload
 
| class="col0 centeralign" | Null Payload
Line 119: Line 173:
 
|- class="row4"
 
|- class="row4"
 
| class="col0" | Total Size:
 
| class="col0" | Total Size:
| class="col1 rightalign" colspan="4" | 18 Bytes + lenght of Null Payload
+
| class="col1 rightalign" colspan="4" | 18 Bytes + length of Null Payload
 
|}
 
|}
 
If the version is different than yours, reply with a  
 
If the version is different than yours, reply with a  
[[#0x1A|ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A)]
+
[[#0x1A|ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A)]]
  
Sent from client after it receives packet 0x1d. The client will repeatedly send this with reducing sizes until it successfully receives a reply. Observed behaviour is that the client will send packets ~0.5s apart in the following way, until it gets a 0x06 response packet, or reaches the end of these:
+
Sent from the client after the player taps on the server in the world list The client will repeatedly send this with reducing sizes until it successfully receives a reply. Observed behaviour is that the client will send packets ~0.5s apart in the following way, until it gets a 0x06 response packet, or reaches the end of these:
4 packets of Null Payload lenght of 1447
+
* 4 packets of Null Payload length of 1447
4 packets of Null Payload lenght of 1155
+
* 4 packets of Null Payload length of 1155
5 packets of Null Payload lenght of 531
+
* 5 packets of Null Payload length of 531
 
If the server doesnt't reply the client, the client will display a "Connect Error" window
 
If the server doesnt't reply the client, the client will display a "Connect Error" window
  
Line 136: Line 190:
  
 
''Server to Client''
 
''Server to Client''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 145: Line 202:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="5" | 0x06
+
| class="col0 centeralign" rowspan="4" | 0x06
 
| class="col1 centeralign" | MAGIC
 
| class="col1 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
Line 164: Line 221:
 
| class="col1 centeralign" | short
 
| class="col1 centeralign" | short
 
| class="col2 centeralign" | <code>1447</code>
 
| class="col2 centeralign" | <code>1447</code>
| class="col3" | Lenght of 0x05. Used to determine packet loss and max UDP packet size (MTU)
+
| class="col3" | length of 0x05. Used to determine packet loss and max UDP packet size (MTU)
 
|- class="row5"
 
|- class="row5"
 
| class="col0" | Total Size:
 
| class="col0" | Total Size:
Line 178: Line 235:
  
 
''Client to Server''
 
''Client to Server''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 187: Line 247:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="6" | 0x07
+
| class="col0 centeralign" rowspan="5" | 0x07
 
| class="col1 centeralign" | MAGIC
 
| class="col1 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
Line 193: Line 253:
 
| class="col4" |  
 
| class="col4" |  
 
|- class="row2"
 
|- class="row2"
| class="col0 centeralign" | Security + Cookie
+
| class="col0 centeralign" | Server Address
 
| class="col1 centeralign" | 1 + 4 bytes
 
| class="col1 centeralign" | 1 + 4 bytes
 
| class="col2 centeralign" | <code>0x043f57fefd</code>
 
| class="col2 centeralign" | <code>0x043f57fefd</code>
| class="col3" | Unused, constant value
+
| class="col3" | 0x4 for IPv4 and the twos complement of each byte of the servers ip address,
 
|- class="row3"
 
|- class="row3"
 
| class="col0 centeralign" | Server UDP Port
 
| class="col0 centeralign" | Server UDP Port
Line 219: Line 279:
 
Sent from client in response to packet 0x06.
 
Sent from client in response to packet 0x06.
  
 +
{{anchor|0x08}}
  
{{anchor|0x08}}
 
 
=== ID_OPEN_CONNECTION_REPLY_2 (0x08) ===
 
=== ID_OPEN_CONNECTION_REPLY_2 (0x08) ===
  
 
''Server to Client''
 
''Server to Client''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 233: Line 296:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="6" | 0x08
+
| class="col0 centeralign" rowspan="5" | 0x08
 
| class="col1 centeralign" | MAGIC
 
| class="col1 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
 
| class="col2 centeralign" | MAGIC
Line 270: Line 333:
  
 
''Server to Client''
 
''Server to Client''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 279: Line 345:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="4" | 0x1A
+
| class="col0 centeralign" rowspan="3" | 0x1A
 
| class="col1 centeralign" | Protocol Version
 
| class="col1 centeralign" | Protocol Version
 
| class="col2 centeralign" | byte
 
| class="col2 centeralign" | byte
Line 299: Line 365:
 
|}
 
|}
  
 +
Sent when the server doesn't support the RakNet protocol specified in 0x05.
  
 
{{anchor|0x1C}}
 
{{anchor|0x1C}}
 +
 
=== ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C) ===
 
=== ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C) ===
  
 
''Server to Client''
 
''Server to Client''
 +
 +
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 313: Line 384:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="5" | 0x1C
+
| class="col0 centeralign" rowspan="4" | 0x1C
 +
| class="col1 centeralign" | Ping ID
 +
| class="col2 centeralign" | int64
 +
| class="col3 centeralign" | <code>0x00000000003c6d0d</code>
 +
| class="col4" | Time since start in Milliseconds
 +
|- class="row2"
 +
| class="col0 centeralign" | Server ID
 +
| class="col1 centeralign" | int64
 +
| class="col2 centeralign" | <code>0x00000000372cdc9e</code>
 +
| class="col3" |
 +
|- class="row3"
 +
| class="col0 centeralign" | MAGIC
 +
| class="col1 centeralign" | MAGIC
 +
| class="col2 centeralign" |
 +
| class="col3" |
 +
|-class="row4"
 +
| class="col0 centeralign" | Identifier
 +
| class="col1 centeralign" | string
 +
| class="col2 centeralign" | "MCPE;Steve;2 7;0.11.0;0;20"
 +
| class="col3" | Used to send the username, format: <code>MCPE;<Server name>;<Protocol version>;<MCPE Version>;<Players>;<Max Players></code>
 +
|- class="row6"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 35 Bytes + Server name length
 +
|}
 +
 
 +
Server sends this packet in response to a 0x01 packet.
 +
If the Server is invisible, this packet will be sent without username
 +
 
 +
<s>In order for the server to show up in the world list, the server name must have "MCCPP;MINECON;" in front of it.</s>
 +
<b>Since MCPE 0.11.0, the server name has a different format.</b>
 +
 
 +
{{anchor|0x1D}}
 +
 
 +
=== ID_ADVERTISE_SYSTEM (0x1D) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
'''RakNet Packet'''
 +
 
 +
'''THIS PACKET IS UNUSED, Use a 0x1c packet instead.'''
 +
 
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="4" | 0x1D
 
| class="col1 centeralign" | Ping ID
 
| class="col1 centeralign" | Ping ID
 
| class="col2 centeralign" | int64
 
| class="col2 centeralign" | int64
Line 331: Line 452:
 
| class="col0 centeralign" | Data
 
| class="col0 centeralign" | Data
 
| class="col1 centeralign" | string
 
| class="col1 centeralign" | string
| class="col2 centeralign" | <code>MCCPP;Demo;Steve</code>
+
| class="col2 centeralign" | <code>MCPE;Steve;2 7;0.11.0;0;20</code>
| class="col3" | Used to send the username (MCCPP;Demo; + username)
+
| class="col3" | Used to send the username, format: MCPE;<Server name>;<Protocol version>;<MCPE Version>;<Players>;<Max Players>
 
|- class="row3"
 
|- class="row3"
 
| class="col0" | Total Size:
 
| class="col0" | Total Size:
| class="col1 rightalign" colspan="4" | 35 Bytes + lenght of string
+
| class="col1 rightalign" colspan="4" | 35 Bytes + length of string
 
|}
 
|}
  
Server sends this packet in response to a 0x02 packet. It may be either a 0x1d or a 0x1c, depending on version.
+
Same as [[#0x1C|ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C)]], but with the Packet ID changed. Depends of the version to send a 0x1D or a 0x1C
If the Server is invisible, this packet will be sent without username
+
 
 +
=== Custom Packet (0x80-0x8F) ===
 +
 
 +
''Two-Way''
  
 +
'''This packet is part of the real Minecraft PE implementation. The structure can change anytime.'''
  
{{anchor|0x1D}}
+
{| class="wikitable"
=== ID_ADVERTISE_SYSTEM (0x1D) ===
+
|- class="row0"
Same as [[#0x1C|ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C)]], but with the Packet ID changed. Depends of the version
+
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="2" | 0x80-0x8F
 +
| class="col1 centeralign" | Count
 +
| class="col2 centeralign" | 3 bytes
 +
| class="col3 centeralign" | <code>0</code>
 +
| class="col4" | Increments once every packet.
 +
|- class="row2"
 +
| class="col2 centeralign" | Data payload
 +
| class="col1 centeralign" |
 +
| class="col2 centeralign" | <code>0x40009000000009...</code>
 +
| class="col3" | Uses [[#Packet_Encapsulation|Packet Encapsulation format]]
 +
 
 +
|- class="row3"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 4 Bytes + payload
 +
|}
  
 +
The receiver will use the Packet number in the 0xC0 packet and send it back.
  
{{anchor|0x84}}
+
{{anchor|0xA0}}
  
=== ID_RESERVED_7 (0x84) ===
+
=== NAK (0xA0) ===
  
 
''Two-Way''
 
''Two-Way''
  
'''This packet is part of the real Minecraft PE implementation. The structure can change anytime.'''
+
'''RakNet Packet'''
 +
 
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="4" | 0xA0
 +
| class="col1 centeralign" | Count
 +
| class="col2 centeralign" | short
 +
| class="col3 centeralign" | <code>1</code>
 +
| class="col4" |
 +
|- class="row2"
 +
| class="col1 centeralign" | MinEqualsMax
 +
| class="col2 centeralign" | boolean
 +
| class="col3 centeralign" | <code>''true''</code>
 +
| class="col4" | ''true'' if the following range contains only one number
 +
|- class="row3"
 +
| class="col1 centeralign" | Packet Number (Min)
 +
| class="col2 centeralign" | 3 bytes
 +
| class="col3 centeralign" | <code>0x000000</code>
 +
| class="col4" | Range of packet to resend
 +
|- class="row4"
 +
| class="col1 centeralign" | Packet Number (Max)
 +
| class="col2 centeralign" | 3 bytes
 +
| class="col3 centeralign" | <code>0x000004</code>
 +
| class="col4" | Range of packet to resend (only if ''false'')
 +
|- class="row5"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 7 or 10 Bytes
 +
|}
 +
 
 +
Send these when a packet was lost, or reply to this resending the lost packet.
  
 +
=== ACK (0xC0) ===
  
This packet has a partial unknown structure
+
''Two-Way''
 +
 
 +
'''RakNet Packet'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 366: Line 550:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="2" | 0x84
+
| class="col0 centeralign" rowspan="4" | 0xC0
| class="col1 centeralign" | Unknown
+
| class="col1 centeralign" | Count
| class="col2 centeralign" | variable
+
| class="col2 centeralign" | short
| class="col3 centeralign" |  
+
| class="col3 centeralign" | <code>1</code>
 
| class="col4" |  
 
| class="col4" |  
 +
|- class="row2"
 +
| class="col1 centeralign" | MinEqualsMax
 +
| class="col2 centeralign" | boolean
 +
| class="col3 centeralign" | <code>''true''</code>
 +
| class="col4" | ''true'' if the following range contains only one number
 +
|- class="row3"
 +
| class="col1 centeralign" | Packet Number (Min)
 +
| class="col2 centeralign" | 3 bytes
 +
| class="col3 centeralign" | <code>0x000000</code>
 +
| class="col4" | Received packet number from field Count in 0x84 and 0x8C
 +
|- class="row4"
 +
| class="col1 centeralign" | Packet Number (Max)
 +
| class="col2 centeralign" | 3 bytes
 +
| class="col3 centeralign" | <code>0x000004</code>
 +
| class="col4" | Received Packet Number (only when ''false'')
 +
|- class="row5"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 7 or 10 Bytes
 +
|}
 +
 +
Sent after a 0x8X. It's used to ACK recieval of packets.
 +
The second packet number is optional and only there when bool is false.
 +
 +
{{anchor|Packet_Encapsulation}}
 +
 +
== Packet Encapsulation format ==
 +
The payload in 0x80-0x8F packets is encoded using different schemes.
 +
To decode them, you've to use the Encapsulation ID to check wich type you should use.
 +
The Encapsulation ID is the first byte of the payload.
 +
 +
Multiple Data Encapsulation packets could be present in one packet. If you want to send data, use 0x00.
 +
 +
<code>Length</code> field is in bits, not bytes. To get the length in bytes, use <code>length_in_bytes = length / 8</code>. The <code>length</code> field is '''excluding''' the header -- both the 0x8X packet header, as well as the encapsulated packet header.
 +
 +
 +
=== 0x00 ===
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Encapsulation ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="2" | 0x00
 +
| class="col1 centeralign" | length
 +
| class="col2 centeralign" | short
 +
| class="col3 centeralign" | <code>0x0090</code>
 +
| class="col4" | Length of Packet in bits
 +
|- class="row2"
 +
| class="col2 centeralign" | Packet
 +
| class="col1 centeralign" | Data Packet
 +
| class="col2 centeralign" | <code>0x09d92145...</code>
 +
| class="col3" |
 +
|- class="row3"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 3 Bytes + Packet Data length
 +
|}
 +
 +
=== 0x40 ===
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Encapsulation ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="3" | 0x40
 +
| class="col1 centeralign" | length
 +
| class="col2 centeralign" | short
 +
| class="col3 centeralign" | <code>0x0090</code>
 +
| class="col4" | Length of Packet in bits
 +
|- class="row2"
 +
| class="col2 centeralign" | Count
 +
| class="col1 centeralign" | 3 bytes
 +
| class="col2 centeralign" | <code>0x000000</code>
 +
| class="col3" | Unknown use
 +
|- class="row3"
 +
| class="col2 centeralign" | Packet
 +
| class="col1 centeralign" | Data Packet
 +
| class="col2 centeralign" | <code>0x09d92145...</code>
 +
| class="col3" |
 +
|- class="row4"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 6 Bytes + Packet Data length
 +
|}
 +
 +
=== 0x60 ===
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Encapsulation ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="4" | 0x60
 +
| class="col1 centeralign" | length
 +
| class="col2 centeralign" | short
 +
| class="col3 centeralign" | <code>0x0090</code>
 +
| class="col4" | Length of Packet in bits
 +
|- class="row2"
 +
| class="col2 centeralign" | Count
 +
| class="col1 centeralign" | 3 bytes
 +
| class="col2 centeralign" | <code>0x000000</code>
 +
| class="col3" | Unknown use
 +
|- class="row3"
 +
| class="col2 centeralign" | Unknown
 +
| class="col1 centeralign" | 4 bytes
 +
| class="col2 centeralign" | <code>0x00000000</code>
 +
| class="col3" | Only sent on first iteration
 +
|- class="row4"
 +
| class="col2 centeralign" | Packet
 +
| class="col1 centeralign" | Data Packet
 +
| class="col2 centeralign" | <code>0x09d92145...</code>
 +
| class="col3" |
 
|- class="row6"
 
|- class="row6"
 
| class="col0" | Total Size:
 
| class="col0" | Total Size:
| class="col1 rightalign" colspan="4" | ? Bytes
+
| class="col1 rightalign" colspan="4" | 12 Bytes + Packet Data length
 
|}
 
|}
  
Sent after 0x08, and 0xC0
 
  
 +
{{anchor|Encapsulated_Login_packets}}
 +
 +
== Encapsulated Login packets ==
 +
 +
After packets 0x05 through 0x08 are sent, the client will send the first encapsulated packets (0x09 through 0x13). After 0x13 the game begins. You can check the login sequence [[Pocket_Editon_Login|here]].
 +
 +
=== Client Connect (0x09) ===
 +
 +
''Client to Server''
 +
 +
'''This is a Data Packet. It is encoded using [[#Packet_Encapsulation|packet encapsulation format]].'''
 +
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="3" | 0x09
 +
| class="col1 centeralign" | clientID
 +
| class="col2 centeralign" | int64
 +
| class="col3 centeralign" | <code></code>
 +
| class="col4" | The mojang client's clientID.
 +
|- class="row2"
 +
| class="col2 centeralign" | session
 +
| class="col1 centeralign" | int64
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | A long that is sent back to the client in 0x10.
 +
|- class="row3"
 +
| class="col2 centeralign" | unknown
 +
| class="col1 centeralign" | byte
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use. Constant value.
 +
 +
|- class="row4"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 18 Bytes
 +
|}
 +
 +
=== Server Handshake (0x10) ===
 +
 +
''Server to Client''
  
{{anchor|0xC0}}
+
'''This is a Data Packet. It is encoded using [[#Packet_Encapsulation|packet encapsulation format]]..'''
=== Unknown (0xC0) ===
 
  
''Two-Way''
+
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="8" | 0x10
 +
| class="col1 centeralign" | Cookie
 +
| class="col2 centeralign" | 4 bytes
 +
| class="col3 centeralign" | <code>043f57fe</code>
 +
| class="col4" | Unknown use, constant value.
 +
|- class="row2"
 +
| class="col2 centeralign" | Security flags
 +
| class="col1 centeralign" | 1 byte
 +
| class="col2 centeralign" | <code>0xcd</code>
 +
| class="col3" | Unknown use, constant value.
 +
|- class="row3"
 +
| class="col2 centeralign" | Server port
 +
| class="col1 centeralign" | short
 +
| class="col2 centeralign" | <code>19132</code>
 +
| class="col3" | Unknown use.
 +
|- class="row4"
 +
| class="col2 centeralign" | Data Array
 +
| class="col1 centeralign" | 70 bytes
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use, constant value (see below).
 +
|- class="row5"
 +
| class="col2 centeralign" | Unknown
 +
| class="col1 centeralign" | 2 bytes
 +
| class="col2 centeralign" | <code>0x00 0x00</code>
 +
| class="col3" | Unknown use, constant value.
 +
|- class="row6"
 +
| class="col2 centeralign" | Session
 +
| class="col1 centeralign" | int64
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Session long recieved in 0x09.
 +
|- class="row7"
 +
| class="col2 centeralign" | Unknown
 +
| class="col1 centeralign" | 8 bytes
 +
| class="col2 centeralign" | <code>0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x0b, 0xa9</code>
 +
| class="col3" | Unknown use, constant value.
 +
 
 +
|- class="row8"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 96 Bytes
 +
|}
 +
 
 +
'''Data Array'''
 +
 
 +
The data array section is unknown, but we do know how to get it right. Below is some code on how to create the array (C#).
 +
 
 +
<code>
 +
 
 +
  public void putDataArray()
 +
        {
 +
            byte[] unknown1 = new byte[] { 0xf5, 0xff, 0xff, 0xf5 };
 +
            byte[] unknown2 = new byte[] { 0xff, 0xff, 0xff, 0xff };
 +
            this.putTriad(unknown1.Length);
 +
            this.putBytes(unknown1);
 +
            for (int i = 0; i < 9; i++)
 +
            {
 +
                this.putTriad(unknown2.Length);
 +
                this.putBytes(unknown2);
 +
            }
 +
        }
 +
</code>
 +
 
 +
A triad is a 3 byte integer.
 +
 
 +
Credit goes to InusualZ (https://github.com/InusualZ/CraftMine/blob/master/src/Network/Packets/Minecraft/ServerHandshake.cs).
 +
 
 +
=== Client Handshake (0x13) ===
 +
 
 +
''Client to Server''
  
'''This packet is part of the real Minecraft PE implementation. The structure can change anytime.'''
+
'''This is a Data Packet. It is encoded using [[#Packet_Encapsulation|packet encapsulation format]]..'''
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 394: Line 812:
 
| class="col4" | Notes
 
| class="col4" | Notes
 
|- class="row1"
 
|- class="row1"
| class="col0 centeralign" rowspan="2" | 0xC0
+
| class="col0 centeralign" rowspan="8" | 0x13
| class="col1 centeralign" | Ping ID
+
| class="col1 centeralign" | cookie
| class="col2 centeralign" | 6 bytes
+
| class="col2 centeralign" | int32
| class="col3 centeralign" | <code>0x000101000000</code>
+
| class="col3 centeralign" | <code>0x43f57fe</code>
| class="col4" |  
+
| class="col4" | Unknown use, same cookie as in 0x10.
 +
|- class="row2"
 +
| class="col2 centeralign" | Security flags
 +
| class="col1 centeralign" | 1 byte
 +
| class="col2 centeralign" | <code>0xcd</code>
 +
| class="col3" | Unknown use, constant value.
 
|- class="row3"
 
|- class="row3"
 +
| class="col2 centeralign" | Server port
 +
| class="col1 centeralign" | short
 +
| class="col2 centeralign" | <code>19132</code>
 +
| class="col3" | Unknown use.
 +
|- class="row4"
 +
| class="col2 centeralign" | Data Array 1 Length + Data Array 1
 +
| class="col1 centeralign" | 1 + ? bytes
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use (see below).
 +
|- class="row5"
 +
| class="col2 centeralign" | Data Array 2
 +
| class="col1 centeralign" | ? bytes
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use, constant value (see below).
 +
|- class="row6"
 +
| class="col2 centeralign" | Timestamp
 +
| class="col1 centeralign" | short
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use.
 +
|- class="row7"
 +
| class="col2 centeralign" | session
 +
| class="col1 centeralign" | int64
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use.
 +
|- class="row8"
 +
| class="col2 centeralign" | session2
 +
| class="col1 centeralign" | int64
 +
| class="col2 centeralign" | <code></code>
 +
| class="col3" | Unknown use.
 +
 +
|- class="row9"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 94 Bytes
 +
|}
 +
 +
'''Data Arrays'''
 +
 +
''Array 1''
 +
 +
The first array is just a series of bytes, starting with the first byte which has the length of the rest of the array. This can be decoded as follows (Java):
 +
 +
<code>
 +
 +
  buffer.get(new byte[(int) buffer.get()]);
 +
 +
</code>
 +
 +
The buffer variable is really a <code>ByteBuffer</code> object found in the package java.nio.
 +
 +
''Array 2''
 +
 +
The second array is a little more complicated. The first section is a triad (3 bytes) which specifies how many bytes to read next. This is repeated 9 times. An example is below (Java):
 +
 +
<code>
 +
for(int i = 0; i < 9; i++){
 +
 +
int l = NetworkUtils.getTriad(buf);
 +
 +
buf.get(new byte[l]);
 +
 +
}
 +
</code>
 +
 +
Again, the buf object is a <code>ByteBuffer</code> object.
 +
 +
 +
=== Client Cancel Connect (0x15) ===
 +
 +
''Client to Server''
 +
 +
'''This is a Data Packet. It is encoded using [[#Packet_Encapsulation|packet encapsulation format]].'''
 +
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="1" | 0x15
 +
| class="col1" | Only the packet ID is sent.
 +
 +
|- class="row2"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="2" | 1 Byte
 +
|}
 +
 +
This appears to be sent whenever the user clicks the "cancel" button when connecting.
 +
 +
== Ping/Pong ==
 +
The client will repeatedly send ping packets to the server each containing an identifier (long). The server then must reply with a pong packet containing the identifier found in the ping. This is observed to happen sometime during the encapsulation login.
 +
 +
=== Ping Packet (0x00) ===
 +
 +
''Client to Server''
 +
 +
'''This is a Data Packet. It is encoded using packet encapsulation.'''
 +
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="2" | 0x00
 +
| class="col1 centeralign" | identifier
 +
| class="col2 centeralign" | int64
 +
| class="col3 centeralign" | <code>0000000000000b3d</code>
 +
| class="col4" | An identifer sent back by a Pong packet (0x03).
 +
 +
|- class="row2"
 
| class="col0" | Total Size:
 
| class="col0" | Total Size:
| class="col1 rightalign" colspan="4" | 7 Bytes
+
| class="col1 rightalign" colspan="4" | 9 Bytes
 
|}
 
|}
  
Sent by the Client after the first 0x84. Then, the Server replies with the same packet
+
=== Pong Packet (0x03) ===
 +
 
 +
''Server to Client''
 +
 
 +
'''This is a Data Packet. It is encoded using packet encapsulation.'''
 +
 
 +
{| class="wikitable"
 +
|- class="row0"
 +
| class="col0" | Packet ID
 +
| class="col1" | Field Name
 +
| class="col2" | Field Type
 +
| class="col3" | Example
 +
| class="col4" | Notes
 +
|- class="row1"
 +
| class="col0 centeralign" rowspan="2" | 0x03
 +
| class="col1 centeralign" | identifier
 +
| class="col2 centeralign" | int64
 +
| class="col3 centeralign" | <code>0000000000000b3d</code>
 +
| class="col4" | The identifier found in the ping packet (0x00).
 +
 
 +
|- class="row2"
 +
| class="col0" | Total Size:
 +
| class="col1 rightalign" colspan="4" | 9 Bytes
 +
|}
 +
 
 +
 
 +
== Data Packets ==
 +
 
 +
This information has been generated using [https://github.com/PocketMine/PocketBurger PocketBurger], then edited manually.
 +
 
 +
'''This information was generated based on:'''
 +
 
 +
'''Minecraft: Pocket Edition v0.7.3, protocol #11'''
 +
 
 +
'''RakNet Protocol version #5'''
 +
 
 +
However, these packets seem to be unchanged since then, and will (most likely) work with the current version.
 +
 
 +
'''Current Version:'''
 +
 
 +
'''Minecraft: Pocket Edition v0.10.4, protocol #20'''
 +
 
 +
'''RakNet Protocol version #5'''
 +
 
 +
=== LoginPacket (0x82) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0x82
 +
| Username
 +
| string8
 +
|
 +
|-
 +
| Protocol #1
 +
| int
 +
|
 +
|-
 +
| Protocol #2
 +
| int
 +
|
 +
|-
 +
| ClientID
 +
| int
 +
|
 +
|-
 +
| Realms Data
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== LoginStatusPacket (0x83) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0x83
 +
| Status
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
The three type of status are:
 +
 
 +
0: Everything is good.
 +
 
 +
1: If the server is outdated.
 +
 +
2. If the game is outdated.
 +
 
 +
If everything is good you need to send StartGamePacket.
 +
 
 +
=== ReadyPacket (0x84) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0x84
 +
| bits[8] Status
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== MessagePacket (0x85) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0x85
 +
| Message
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetTimePacket (0x86) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0x86
 +
| Time
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== StartGamePacket (0x87) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="7" | 0x87
 +
| level seed
 +
| int
 +
|
 +
|-
 +
| Unknown
 +
| int
 +
|
 +
|-
 +
| Gamemode
 +
| int
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AddMobPacket (0x88) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="8" | 0x88
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Type
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| yaw
 +
| byte
 +
|
 +
|-
 +
| pitch
 +
| byte
 +
|
 +
|-
 +
| Metadata
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AddPlayerPacket (0x89) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="11" | 0x89
 +
| (unsigned) Client ID
 +
| long
 +
|
 +
|-
 +
| Username
 +
| string8
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Yaw
 +
| byte
 +
|
 +
|-
 +
| Pitch
 +
| byte
 +
|
 +
|-
 +
| Unknown
 +
| short
 +
|
 +
|-
 +
| Unknown
 +
| short
 +
|
 +
|-
 +
| Metadata
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== RemovePlayerPacket (0x8a) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0x8a
 +
| entity ID
 +
| int
 +
|
 +
|-
 +
| (unsigned) Client ID
 +
| long
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AddEntityPacket (0x8c) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="9" | 0x8c
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Type
 +
| byte
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Did?
 +
| int
 +
| If this int > 0 you can send the next parameter
 +
|-
 +
| SpeedX
 +
| short
 +
|
 +
|-
 +
| SpeedY
 +
| short
 +
|
 +
|-
 +
| SpeedZ
 +
| short
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== RemoveEntityPacket (0x8d) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0x8d
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AddItemEntityPacket (0x8e) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="10" | 0x8e
 +
| Enity ID
 +
| int
 +
|
 +
|-
 +
| Block
 +
| short
 +
|
 +
|-
 +
| Stack
 +
| byte
 +
|
 +
|-
 +
| Meta
 +
| short
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Yaw
 +
| byte
 +
|
 +
|-
 +
| Pitch
 +
| byte
 +
|
 +
|-
 +
| Roll
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== TakeItemEntityPacket (0x8f) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0x8f
 +
| Target
 +
| int
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== MoveEntityPacket (0x90) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0x90
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== MoveEntityPacket_PosRot (0x93) ===
 +
 
 +
''None''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="6" | 0x93
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Yaw
 +
| float
 +
|
 +
|-
 +
| Pitch
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== MovePlayerPacket (0x94) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="6" | 0x94
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Yaw
 +
| float
 +
|
 +
|-
 +
| Pitch
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== PlaceBlockPacket (0x95) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="7" | 0x95
 +
| Entity iD
 +
| int
 +
|
 +
|-
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Y
 +
| byte
 +
|
 +
|-
 +
| Block
 +
| byte
 +
|
 +
|-
 +
| Meta
 +
| byte
 +
|
 +
|-
 +
| Face
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== RemoveBlockPacket (0x96) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0x96
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Y
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== UpdateBlockPacket (0x97) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="6" | 0x97
 +
| Entiy ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Y
 +
| byte
 +
|
 +
|-
 +
| Block
 +
| byte
 +
|
 +
|-
 +
| Meta
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AddPaintingPacket (0x98) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="6" | 0x98
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| int
 +
|
 +
|-
 +
| Y
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Direction
 +
| int
 +
|
 +
|-
 +
| Title
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ExplodePacket (0x99) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="8" | 0x99
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
| Radius
 +
| float
 +
|
 +
|-
 +
| Count
 +
| int
 +
|
 +
|-
 +
| Records
 +
| byte
 +
|
 +
|-
 +
| Counts?
 +
| byte
 +
|
 +
|-
 +
| Records?
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== LevelEventPacket (0x9a) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0x9a
 +
| Unknown?
 +
| short
 +
|
 +
|-
 +
| Unknown?
 +
| short
 +
|
 +
|-
 +
| Unknown?
 +
| short
 +
|
 +
|-
 +
| Unknown?
 +
| short
 +
|
 +
|-
 +
| Unknown?
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== TileEventPacket (0x9b) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0x9b
 +
| X
 +
| int
 +
|
 +
|-
 +
| Y
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Case 1
 +
| int
 +
|
 +
|-
 +
| Case 2
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== EntityEventPacket (0x9c) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0x9c
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Event
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== RequestChunkPacket (0x9d) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0x9d
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ChunkDataPacket (0x9e) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0x9e
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-Data?
 +
| byte
 +
|
 +
|-
 +
| Data?
 +
| byte[]
 +
|
 +
|-
 +
| Data?
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== PlayerEquipmentPacket (0x9f) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0x9f
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Block
 +
| short
 +
|
 +
|-
 +
| Meta
 +
| short
 +
|
 +
|-
 +
| Slot
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== PlayerArmorEquipmentPacket (0xa0) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0xa0
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Slot 1
 +
| byte
 +
|
 +
|-
 +
| Slot 2
 +
| byte
 +
|
 +
|-
 +
| Slot 3
 +
| byte
 +
|
 +
|-
 +
| Slot 4
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== InteractPacket (0xa1) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="3" | 0xa1
 +
| Action
 +
| byte[]
 +
|
 +
|-
 +
| entity ID
 +
| int
 +
|
 +
|-
 +
| Target
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== UseItemPacket (0xa2) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="13" | 0xa2
 +
| X
 +
| int
 +
|
 +
|-
 +
| Y
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Face
 +
| int
 +
|
 +
|-
 +
| Block
 +
| byte[]
 +
|
 +
|-
 +
| Meta
 +
| byte
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Fx
 +
| float
 +
|
 +
|-
 +
| Fy
 +
| float
 +
|
 +
|-
 +
| Fz
 +
| float
 +
|
 +
|-
 +
| PosX
 +
| float
 +
|
 +
|-
 +
| PosY
 +
| float
 +
|
 +
|-
 +
| PosZ
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== PlayerActionPacket (0xa3) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="6" | 0xa3
 +
| Action
 +
| int
 +
|
 +
|-
 +
| X
 +
| int
 +
|
 +
|-
 +
| Y
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Face
 +
| int
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== HurtArmorPacket (0xa5) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0xa5
 +
| Health
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetEntityDataPacket (0xa6) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0xa6
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Metadata
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetEntityMotionPacket (0xa7) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0xa7
 +
| Unknown?
 +
| byte
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| short
 +
|
 +
|-
 +
| Y
 +
| short
 +
|
 +
|-
 +
| Z
 +
| short
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetRidingPacket (0xa8) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0xa8
 +
| a
 +
| int
 +
|
 +
|-
 +
| b
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetHealthPacket (0xa9) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0xa9
 +
| Health
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SetSpawnPositionPacket (0xaa) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="3" | 0xaa
 +
| X
 +
| int
 +
|
 +
|-
 +
| Z
 +
| int
 +
|
 +
|-
 +
| Y
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AnimatePacket (0xab) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0xab
 +
| Action
 +
| byte
 +
|
 +
|-
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== RespawnPacket (0xac) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0xac
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| X
 +
| float
 +
|
 +
|-
 +
| Y
 +
| float
 +
|
 +
|-
 +
| Z
 +
| float
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SendInventoryPacket (0xad) ===
 +
 
 +
''None''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0xad
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Windows ID
 +
| byte
 +
|
 +
|-
 +
| Count
 +
| short
 +
|
 +
|-
 +
| Slots
 +
| byte[]
 +
|
 +
|-
 +
| Items
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== DropItemPacket (0xae) ===
 +
 
 +
''Server to Client''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0xae
 +
| Entity ID
 +
| int
 +
|
 +
|-
 +
| Unknown?
 +
| byte
 +
|
 +
|-
 +
| Block
 +
| short
 +
|
 +
|-
 +
| Stack
 +
| byte
 +
|
 +
|-
 +
| Meta
 +
| short
 +
|
 +
|-
 +
 +
|}
 +
 
 +
=== ContainerOpenPacket (0xaf) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0xaf
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
| Type
 +
| byte
 +
|
 +
|-
 +
| Slot
 +
| byte
 +
|
 +
|-
 +
| Title
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ContainerClosePacket (0xb0) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0xb0
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ContainerSetSlotPacket (0xb1) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="5" | 0xb1
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
| Slot
 +
| short
 +
|
 +
|-
 +
| Block
 +
| short
 +
|
 +
|-
 +
| Stack
 +
| byte
 +
|
 +
|-
 +
| Meta
 +
| short
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ContainerSetDataPacket (0xb2) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="3" | 0xb2
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
| Property
 +
| short
 +
|
 +
|-
 +
| Value
 +
| short
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ContainerSetContentPacket (0xb3) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="3" | 0xb3
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
| Count
 +
| short
 +
|
 +
|-
 +
| Items
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ContainerAckPacket (0xb4) ===
 +
 
 +
''None''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="2" | 0xb4
 +
| Window ID
 +
| byte
 +
|
 +
|-
 +
| Unknown?
 +
| short
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== ChatPacket (0xb5) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0xb5
 +
| Message
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== SignUpdatePacket (0xb6) ===
 +
 
 +
''Two-Way''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="4" | 0xb6
 +
| X
 +
| short
 +
|
 +
|-
 +
| Y
 +
| byte
 +
|
 +
|-
 +
| Z
 +
| short
 +
|
 +
|-
 +
| Lines
 +
| string8
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
=== AdventureSettingsPacket (0xb7) ===
 +
 
 +
''Client to Server''
 +
 
 +
 
 +
{| class="wikitable"
 +
|-
 +
| Packet ID
 +
| Field Name
 +
| Field Type
 +
| Notes
 +
|-
 +
| rowspan="1" | 0xb7
 +
| Flags
 +
| byte[]
 +
|
 +
|-
 +
 
 +
|}
 +
 
 +
 
  
 
[[Category:Pocket Minecraft]]
 
[[Category:Pocket Minecraft]]

Latest revision as of 23:48, 12 May 2023

Heads up!

This is outdated information for Minecraft Pocket Edition.. For the latest Bedrock Edition protocol documentation see Bedrock Protocol.

Unlike the Minecraft protocol, this protocol uses UDP with (so far observed, at least) one message per packet. This makes the protocol easier to work with when it comes to packet serialization, and might offer latency improvements, but will inevitably have the usual UDP issues (packets lost, truncated, duplicated, out-of-order, etc.).

As of 0.9.0, clients appear to search for servers on only port 19132.

Clients don't pick any specific port to listen on.


Please note that even where packet field names are written in this page, these are still largely hypothetical and could well be incorrect guesses. Some packets are fixed to the RakNet protocol, and will be marked as "RakNet Packet", which means that these packets will not change on future versions.

It has been determined that PM uses RakNet for its networking library, some documentation that seems relevant.


The login sequence is not covered by this page.


Contents

Terminology

PM
Pocket Minecraft (aka Minecraft PE or Minecraft Pocket Edition)

Types

Size Range Notes
byte 1 -128 to 127 Signed, two's complement
short 2 -32768 to 32767 Signed, two's complement
int32 4 -2147483648 to 2147483647 Signed, two's complement
int64 8 Maybe a double?
MAGIC 16 0x00ffff00fefefefefdfdfdfd12345678 always those hex bytes, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID
string = 1 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{|}~

Login Packets

All packets start with a single byte that identifies the packet type, the rest of the packet follows it. Please note that packets 0x09 through 0x13 are not documented (yet).


ID_CONNECTED_PING_OPEN_CONNECTIONS (0x01)

Client to Broadcast


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x01 Ping ID int64 0x00000000003c6d0d Time since start in Milliseconds
MAGIC MAGIC
Total Size: 25 Bytes

Clients start out by sending this packet to the IP broadcast address on port 19132 repeatedly (approx once per second) when joining a server was chosen on the main screen, and stops when the user selects a server (or leaves the screen). The ping ID from the client increases over time, and appears to be the number of milliseconds since the client program was started (might be used to measure server response latency).


ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x02)

Client to Broadcast

NOTE: THIS PACKET APPEARS TO BE UNUSED. Use a 0x01 packet instead

RakNet Packet

Packet ID Field Name Field Type Example Notes
0x02 Ping ID int64 0x00000000003c6d0d Time since start in Milliseconds
MAGIC MAGIC
Total Size: 25 Bytes

Same as ID_CONNECTED_PING_OPEN_CONNECTIONS (0x01), but with the Packet ID changed.


ID_OPEN_CONNECTION_REQUEST_1 (0x05)

Client to Server


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x05 MAGIC MAGIC
RakNet Protocol Version byte 5 Check the Data Packet section for the current version
Null Payload many 0x00 bytes 0x00 * 1447 MTU (Maximum Transport Unit)
Total Size: 18 Bytes + length of Null Payload

If the version is different than yours, reply with a ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A)

Sent from the client after the player taps on the server in the world list The client will repeatedly send this with reducing sizes until it successfully receives a reply. Observed behaviour is that the client will send packets ~0.5s apart in the following way, until it gets a 0x06 response packet, or reaches the end of these:

  • 4 packets of Null Payload length of 1447
  • 4 packets of Null Payload length of 1155
  • 5 packets of Null Payload length of 531

If the server doesnt't reply the client, the client will display a "Connect Error" window


ID_OPEN_CONNECTION_REPLY_1 (0x06)

Server to Client


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x06 MAGIC MAGIC
Server ID int64 0x00000000372cdc9e This value seems to be constant for an installation of PM, or differs between the demo and full version.
Server Security byte 0 Always 0
MTU Size short 1447 length of 0x05. Used to determine packet loss and max UDP packet size (MTU)
Total Size: 28 Bytes

Sent from server after it receives packet 0x05.


ID_OPEN_CONNECTION_REQUEST_2 (0x07)

Client to Server


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x07 MAGIC MAGIC
Server Address 1 + 4 bytes 0x043f57fefd 0x4 for IPv4 and the twos complement of each byte of the servers ip address,
Server UDP Port short 19132
MTU Size short 1464
Client ID int64 0x00000000372cdc9e The Client / Server ID will be the same for a given device
Total Size: 34 Bytes

Sent from client in response to packet 0x06.


ID_OPEN_CONNECTION_REPLY_2 (0x08)

Server to Client


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x08 MAGIC MAGIC
Server ID int64 0x00000000372cdc9e
Client UDP Port short 46946
MTU Size short 1464
Security byte 0 Always 0
Total Size: 30 Bytes

Sent from server in response to packet 0x07.


ID_INCOMPATIBLE_PROTOCOL_VERSION (0x1A)

Server to Client


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x1A Protocol Version byte 5
MAGIC MAGIC
Server ID int64 0x00000000372cdc9e
Total Size: 26 Bytes

Sent when the server doesn't support the RakNet protocol specified in 0x05.


ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C)

Server to Client


RakNet Packet

Packet ID Field Name Field Type Example Notes
0x1C Ping ID int64 0x00000000003c6d0d Time since start in Milliseconds
Server ID int64 0x00000000372cdc9e
MAGIC MAGIC
Identifier string "MCPE;Steve;2 7;0.11.0;0;20" Used to send the username, format: MCPE;<Server name>;<Protocol version>;<MCPE Version>;<Players>;<Max Players>
Total Size: 35 Bytes + Server name length

Server sends this packet in response to a 0x01 packet. If the Server is invisible, this packet will be sent without username

In order for the server to show up in the world list, the server name must have "MCCPP;MINECON;" in front of it. Since MCPE 0.11.0, the server name has a different format.


ID_ADVERTISE_SYSTEM (0x1D)

Server to Client


RakNet Packet

THIS PACKET IS UNUSED, Use a 0x1c packet instead.

Packet ID Field Name Field Type Example Notes
0x1D Ping ID int64 0x00000000003c6d0d Time since start in Milliseconds
Server ID int64 0x00000000372cdc9e
MAGIC MAGIC
Data string MCPE;Steve;2 7;0.11.0;0;20 Used to send the username, format: MCPE;<Server name>;<Protocol version>;<MCPE Version>;<Players>;<Max Players>
Total Size: 35 Bytes + length of string

Same as ID_UNCONNECTED_PING_OPEN_CONNECTIONS (0x1C), but with the Packet ID changed. Depends of the version to send a 0x1D or a 0x1C

Custom Packet (0x80-0x8F)

Two-Way

This packet is part of the real Minecraft PE implementation. The structure can change anytime.

Packet ID Field Name Field Type Example Notes
0x80-0x8F Count 3 bytes 0 Increments once every packet.
Data payload 0x40009000000009... Uses Packet Encapsulation format
Total Size: 4 Bytes + payload

The receiver will use the Packet number in the 0xC0 packet and send it back.


NAK (0xA0)

Two-Way

RakNet Packet

Packet ID Field Name Field Type Example Notes
0xA0 Count short 1
MinEqualsMax boolean true true if the following range contains only one number
Packet Number (Min) 3 bytes 0x000000 Range of packet to resend
Packet Number (Max) 3 bytes 0x000004 Range of packet to resend (only if false)
Total Size: 7 or 10 Bytes

Send these when a packet was lost, or reply to this resending the lost packet.

ACK (0xC0)

Two-Way

RakNet Packet

Packet ID Field Name Field Type Example Notes
0xC0 Count short 1
MinEqualsMax boolean true true if the following range contains only one number
Packet Number (Min) 3 bytes 0x000000 Received packet number from field Count in 0x84 and 0x8C
Packet Number (Max) 3 bytes 0x000004 Received Packet Number (only when false)
Total Size: 7 or 10 Bytes

Sent after a 0x8X. It's used to ACK recieval of packets. The second packet number is optional and only there when bool is false.


Packet Encapsulation format

The payload in 0x80-0x8F packets is encoded using different schemes. To decode them, you've to use the Encapsulation ID to check wich type you should use. The Encapsulation ID is the first byte of the payload.

Multiple Data Encapsulation packets could be present in one packet. If you want to send data, use 0x00.

Length field is in bits, not bytes. To get the length in bytes, use length_in_bytes = length / 8. The length field is excluding the header -- both the 0x8X packet header, as well as the encapsulated packet header.


0x00

Encapsulation ID Field Name Field Type Example Notes
0x00 length short 0x0090 Length of Packet in bits
Packet Data Packet 0x09d92145...
Total Size: 3 Bytes + Packet Data length

0x40

Encapsulation ID Field Name Field Type Example Notes
0x40 length short 0x0090 Length of Packet in bits
Count 3 bytes 0x000000 Unknown use
Packet Data Packet 0x09d92145...
Total Size: 6 Bytes + Packet Data length

0x60

Encapsulation ID Field Name Field Type Example Notes
0x60 length short 0x0090 Length of Packet in bits
Count 3 bytes 0x000000 Unknown use
Unknown 4 bytes 0x00000000 Only sent on first iteration
Packet Data Packet 0x09d92145...
Total Size: 12 Bytes + Packet Data length


Encapsulated Login packets

After packets 0x05 through 0x08 are sent, the client will send the first encapsulated packets (0x09 through 0x13). After 0x13 the game begins. You can check the login sequence here.

Client Connect (0x09)

Client to Server

This is a Data Packet. It is encoded using packet encapsulation format.

Packet ID Field Name Field Type Example Notes
0x09 clientID int64 The mojang client's clientID.
session int64 A long that is sent back to the client in 0x10.
unknown byte Unknown use. Constant value.
Total Size: 18 Bytes

Server Handshake (0x10)

Server to Client

This is a Data Packet. It is encoded using packet encapsulation format..

Packet ID Field Name Field Type Example Notes
0x10 Cookie 4 bytes 043f57fe Unknown use, constant value.
Security flags 1 byte 0xcd Unknown use, constant value.
Server port short 19132 Unknown use.
Data Array 70 bytes Unknown use, constant value (see below).
Unknown 2 bytes 0x00 0x00 Unknown use, constant value.
Session int64 Session long recieved in 0x09.
Unknown 8 bytes 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x0b, 0xa9 Unknown use, constant value.
Total Size: 96 Bytes

Data Array

The data array section is unknown, but we do know how to get it right. Below is some code on how to create the array (C#).

  public void putDataArray()
       {
           byte[] unknown1 = new byte[] { 0xf5, 0xff, 0xff, 0xf5 };
           byte[] unknown2 = new byte[] { 0xff, 0xff, 0xff, 0xff };
           this.putTriad(unknown1.Length);
           this.putBytes(unknown1);
           for (int i = 0; i < 9; i++)
           {
               this.putTriad(unknown2.Length);
               this.putBytes(unknown2);
           }
       }

A triad is a 3 byte integer.

Credit goes to InusualZ (https://github.com/InusualZ/CraftMine/blob/master/src/Network/Packets/Minecraft/ServerHandshake.cs).

Client Handshake (0x13)

Client to Server

This is a Data Packet. It is encoded using packet encapsulation format..

Packet ID Field Name Field Type Example Notes
0x13 cookie int32 0x43f57fe Unknown use, same cookie as in 0x10.
Security flags 1 byte 0xcd Unknown use, constant value.
Server port short 19132 Unknown use.
Data Array 1 Length + Data Array 1 1 + ? bytes Unknown use (see below).
Data Array 2 ? bytes Unknown use, constant value (see below).
Timestamp short Unknown use.
session int64 Unknown use.
session2 int64 Unknown use.
Total Size: 94 Bytes

Data Arrays

Array 1

The first array is just a series of bytes, starting with the first byte which has the length of the rest of the array. This can be decoded as follows (Java):

  buffer.get(new byte[(int) buffer.get()]);

The buffer variable is really a ByteBuffer object found in the package java.nio.

Array 2

The second array is a little more complicated. The first section is a triad (3 bytes) which specifies how many bytes to read next. This is repeated 9 times. An example is below (Java):

for(int i = 0; i < 9; i++){

int l = NetworkUtils.getTriad(buf);

buf.get(new byte[l]);

}

Again, the buf object is a ByteBuffer object.


Client Cancel Connect (0x15)

Client to Server

This is a Data Packet. It is encoded using packet encapsulation format.

Packet ID Notes
0x15 Only the packet ID is sent.
Total Size: 1 Byte

This appears to be sent whenever the user clicks the "cancel" button when connecting.

Ping/Pong

The client will repeatedly send ping packets to the server each containing an identifier (long). The server then must reply with a pong packet containing the identifier found in the ping. This is observed to happen sometime during the encapsulation login.

Ping Packet (0x00)

Client to Server

This is a Data Packet. It is encoded using packet encapsulation.

Packet ID Field Name Field Type Example Notes
0x00 identifier int64 0000000000000b3d An identifer sent back by a Pong packet (0x03).
Total Size: 9 Bytes

Pong Packet (0x03)

Server to Client

This is a Data Packet. It is encoded using packet encapsulation.

Packet ID Field Name Field Type Example Notes
0x03 identifier int64 0000000000000b3d The identifier found in the ping packet (0x00).
Total Size: 9 Bytes


Data Packets

This information has been generated using PocketBurger, then edited manually.

This information was generated based on:

Minecraft: Pocket Edition v0.7.3, protocol #11

RakNet Protocol version #5

However, these packets seem to be unchanged since then, and will (most likely) work with the current version.

Current Version:

Minecraft: Pocket Edition v0.10.4, protocol #20

RakNet Protocol version #5

LoginPacket (0x82)

Client to Server


Packet ID Field Name Field Type Notes
0x82 Username string8
Protocol #1 int
Protocol #2 int
ClientID int
Realms Data string8

LoginStatusPacket (0x83)

Server to Client


Packet ID Field Name Field Type Notes
0x83 Status int

The three type of status are:

0: Everything is good.

1: If the server is outdated.

2. If the game is outdated.

If everything is good you need to send StartGamePacket.

ReadyPacket (0x84)

Client to Server


Packet ID Field Name Field Type Notes
0x84 bits[8] Status byte

MessagePacket (0x85)

Two-Way


Packet ID Field Name Field Type Notes
0x85 Message string8

SetTimePacket (0x86)

Client to Server


Packet ID Field Name Field Type Notes
0x86 Time int

StartGamePacket (0x87)

Client to Server


Packet ID Field Name Field Type Notes
0x87 level seed int
Unknown int
Gamemode int
Entity ID int
X float
Y float
Z float

AddMobPacket (0x88)

Client to Server


Packet ID Field Name Field Type Notes
0x88 Entity ID int
Type int
X float
Y float
Z float
yaw byte
pitch byte
Metadata byte[]

AddPlayerPacket (0x89)

Client to Server


Packet ID Field Name Field Type Notes
0x89 (unsigned) Client ID long
Username string8
Entity ID int
X float
Y float
Z float
Yaw byte
Pitch byte
Unknown short
Unknown short
Metadata byte[]

RemovePlayerPacket (0x8a)

Client to Server


Packet ID Field Name Field Type Notes
0x8a entity ID int
(unsigned) Client ID long

AddEntityPacket (0x8c)

Client to Server


Packet ID Field Name Field Type Notes
0x8c Entity ID int
Type byte
X float
Y float
Z float
Did? int If this int > 0 you can send the next parameter
SpeedX short
SpeedY short
SpeedZ short

RemoveEntityPacket (0x8d)

Client to Server


Packet ID Field Name Field Type Notes
0x8d Entity ID int

AddItemEntityPacket (0x8e)

Client to Server


Packet ID Field Name Field Type Notes
0x8e Enity ID int
Block short
Stack byte
Meta short
X float
Y float
Z float
Yaw byte
Pitch byte
Roll byte

TakeItemEntityPacket (0x8f)

Client to Server


Packet ID Field Name Field Type Notes
0x8f Target int
Entity ID int

MoveEntityPacket (0x90)

Client to Server


Packet ID Field Name Field Type Notes
0x90 Entity ID int
X float
Y float
Z float

MoveEntityPacket_PosRot (0x93)

None


Packet ID Field Name Field Type Notes
0x93 Entity ID int
X float
Y float
Z float
Yaw float
Pitch float

MovePlayerPacket (0x94)

Two-Way


Packet ID Field Name Field Type Notes
0x94 Entity ID int
X float
Y float
Z float
Yaw float
Pitch float

PlaceBlockPacket (0x95)

Two-Way


Packet ID Field Name Field Type Notes
0x95 Entity iD int
X int
Z int
Y byte
Block byte
Meta byte
Face byte

RemoveBlockPacket (0x96)

Server to Client


Packet ID Field Name Field Type Notes
0x96 Entity ID int
X int
Z int
Y byte

UpdateBlockPacket (0x97)

Client to Server


Packet ID Field Name Field Type Notes
0x97 Entiy ID int
X int
Z int
Y byte
Block byte
Meta byte

AddPaintingPacket (0x98)

Client to Server


Packet ID Field Name Field Type Notes
0x98 Entity ID int
X int
Y int
Z int
Direction int
Title string8

ExplodePacket (0x99)

Client to Server


Packet ID Field Name Field Type Notes
0x99 X float
Y float
Z float
Radius float
Count int
Records byte
Counts? byte
Records? byte

LevelEventPacket (0x9a)

Client to Server


Packet ID Field Name Field Type Notes
0x9a Unknown? short
Unknown? short
Unknown? short
Unknown? short
Unknown? int

TileEventPacket (0x9b)

Client to Server


Packet ID Field Name Field Type Notes
0x9b X int
Y int
Z int
Case 1 int
Case 2 int

EntityEventPacket (0x9c)

Two-Way


Packet ID Field Name Field Type Notes
0x9c Entity ID int
Event byte

RequestChunkPacket (0x9d)

Server to Client


Packet ID Field Name Field Type Notes
0x9d X int
Z int

ChunkDataPacket (0x9e)

Client to Server


Packet ID Field Name Field Type Notes
0x9e X int
Z int
byte
Data? byte[]
Data? byte[]

PlayerEquipmentPacket (0x9f)

Two-Way


Packet ID Field Name Field Type Notes
0x9f Entity ID int
Block short
Meta short
Slot byte

PlayerArmorEquipmentPacket (0xa0)

Two-Way


Packet ID Field Name Field Type Notes
0xa0 Entity ID int
Slot 1 byte
Slot 2 byte
Slot 3 byte
Slot 4 byte

InteractPacket (0xa1)

Two-Way


Packet ID Field Name Field Type Notes
0xa1 Action byte[]
entity ID int
Target int

UseItemPacket (0xa2)

Server to Client


Packet ID Field Name Field Type Notes
0xa2 X int
Y int
Z int
Face int
Block byte[]
Meta byte
Entity ID int
Fx float
Fy float
Fz float
PosX float
PosY float
PosZ float

PlayerActionPacket (0xa3)

Server to Client


Packet ID Field Name Field Type Notes
0xa3 Action int
X int
Y int
Z int
Face int
Entity ID int

HurtArmorPacket (0xa5)

Client to Server


Packet ID Field Name Field Type Notes
0xa5 Health byte

SetEntityDataPacket (0xa6)

Client to Server


Packet ID Field Name Field Type Notes
0xa6 Entity ID int
Metadata byte[]

SetEntityMotionPacket (0xa7)

Client to Server


Packet ID Field Name Field Type Notes
0xa7 Unknown? byte
Entity ID int
X short
Y short
Z short

SetRidingPacket (0xa8)

Client to Server


Packet ID Field Name Field Type Notes
0xa8 a int
b int

SetHealthPacket (0xa9)

Two-Way


Packet ID Field Name Field Type Notes
0xa9 Health byte

SetSpawnPositionPacket (0xaa)

Client to Server


Packet ID Field Name Field Type Notes
0xaa X int
Z int
Y byte

AnimatePacket (0xab)

Two-Way


Packet ID Field Name Field Type Notes
0xab Action byte
Entity ID int

RespawnPacket (0xac)

Two-Way


Packet ID Field Name Field Type Notes
0xac Entity ID int
X float
Y float
Z float

SendInventoryPacket (0xad)

None


Packet ID Field Name Field Type Notes
0xad Entity ID int
Windows ID byte
Count short
Slots byte[]
Items byte[]

DropItemPacket (0xae)

Server to Client


Packet ID Field Name Field Type Notes
0xae Entity ID int
Unknown? byte
Block short
Stack byte
Meta short

ContainerOpenPacket (0xaf)

Client to Server


Packet ID Field Name Field Type Notes
0xaf Window ID byte
Type byte
Slot byte
Title string8

ContainerClosePacket (0xb0)

Two-Way


Packet ID Field Name Field Type Notes
0xb0 Window ID byte

ContainerSetSlotPacket (0xb1)

Two-Way


Packet ID Field Name Field Type Notes
0xb1 Window ID byte
Slot short
Block short
Stack byte
Meta short

ContainerSetDataPacket (0xb2)

Client to Server


Packet ID Field Name Field Type Notes
0xb2 Window ID byte
Property short
Value short

ContainerSetContentPacket (0xb3)

Client to Server


Packet ID Field Name Field Type Notes
0xb3 Window ID byte
Count short
Items byte[]

ContainerAckPacket (0xb4)

None


Packet ID Field Name Field Type Notes
0xb4 Window ID byte
Unknown? short

ChatPacket (0xb5)

Client to Server


Packet ID Field Name Field Type Notes
0xb5 Message string8

SignUpdatePacket (0xb6)

Two-Way


Packet ID Field Name Field Type Notes
0xb6 X short
Y byte
Z short
Lines string8

AdventureSettingsPacket (0xb7)

Client to Server


Packet ID Field Name Field Type Notes
0xb7 Flags byte[]