Difference between revisions of "Raknet Protocol"
m (Fix typo) |
m (Fix rowspan for Incompatible protocol) |
||
Line 376: | Line 376: | ||
! Notes | ! Notes | ||
|- | |- | ||
− | |rowspan=" | + | |rowspan="3"| 0x19 |
| Protocol | | Protocol | ||
| byte | | byte |
Revision as of 10:09, 9 June 2020
- Remember that this page is a WIP. Come back later to see a more complete page.
RakNet is a networking library used by Minecraft Bedrock Edition. You might want to also look at the documentation for the Bedrock Protocol.
This is based on the old Pocket Edition Protocol Documentation and may be incomplete or outdated.
The source code for the RakNet Library can be found here.
NOTE:
You may want to use an existing library if one exists for your language of choice.
Here is an incomplete list. Not all of these are maintained or complete. If these are outdated you may need to change the protocol version to 9 before it can work. The protocol doesn't seem to have had any significant changes since the official implementation was discontinued in 2014, so as long as you bump the protocol version older libraries are likely to still work.
Name | Description | Language | License | Active development |
---|---|---|---|---|
NukkitX Network | Network components used within NukkitX, but with great support for general use as well | Java | Apache License | Yes |
JRakNet | JRakNet is a networking library for Java which implements the UDP based protocol RakNet | Java | MIT | Yes |
JRakLibPlus | A library for easy creation of RakNet servers, based on RakLib and JRakLib. | Java | LGPL | No |
RakLib | RakNet server implementation written in PHP. This library is very lightweight on actual implementation - it provides the bare minimum to get a Minecraft Pocket Edition server functional. It only currently provides server functionality, and does not support most RakNet features. | PHP | GPL | Yes |
raknet | UDP network library that follows the RakNet protocol for Node.js | node.js | MIT | No |
PyRakLib | PyRakLib is a networking library that follows the RakNet protocol for MCPE. It is ported from the PHP library RakLib. | Python | GPL | No |
Raknet (official) | The official implementation. Outdated and mostly for reference purposes. May not work with the latest Bedrock. | C++ | BSD | No |
Contents
- 1 Data types
- 2 Handshake sequence
- 3 Packets
- 3.1 Unconnected Ping
- 3.2 Unconnected Pong
- 3.3 Connected Ping
- 3.4 Connected Pong
- 3.5 Offline Connection Request 1
- 3.6 Offline Connection Response 1
- 3.7 Offline Connection Request 2
- 3.8 Offline Connection Response 2
- 3.9 Online Connection Request
- 3.10 Online Connection Request Accepted
- 3.11 Incompatible protocol
- 3.12 Unconnected Ping
- 3.13 Frame Set Packet
- 3.14 Game Packet
- 3.15 NACK
- 3.16 ACK
Data types
Size (Bytes) | Range | Notes | |
---|---|---|---|
Byte | 1 | 0 to 255 | |
Long | 8 | -2^63 to 2^63-1 | Signed 64-bit Integer |
Magic | 16 | 00ffff00fefefefefdfdfdfd12345678
|
Always those hex bytes, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID |
short | 2 | -32768 to 32767 | |
unsigned short | 2 | 0 to 65535 | |
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{|}~ |
byte | 1 | 0 to 255 | |
boolean | 1 | 0 to 1 | True is encoded as 0x01 , false as 0x00 .
|
address | 7 | 1 byte for the IP version (4 or 6), followed by (for IPv4) 4 bytes for the IP and an unsigned short for the port number |
Handshake sequence
- C→S: Offline Connection Request 1
- S→C: Offline Connection Response 1
- C→S: Offline Connection Request 2
- S→C: Offline Connection Response 2
This is currently incomplete
Packets
Unconnected Ping
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x01, 0x02 | Time | Long | |
MAGIC | magic | ||
Client GUID | Long |
0x02
is only replied to if there are open connections to the server. Note: as of 0.15.6 it seems that the game refreshes it's LAN world list every 4-5 seconds, however it seems the game will still ping in 1 second intervals.
This packet should be responded to with unconnected Pong.
Unconnected Pong
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x1c | Time | Long | |
Server GUID | Long | ||
MAGIC | magic | ||
Server ID string | string | Used for the MOTD. See below for details. |
Server ID string format
For Minecraft Bedrock this is separated by semicolons and uses the following format:
Edition (MCPE or MCEE for Education Edition);MOTD line 1;Protocol Version;Version Name;Player Count;Max Player Count;Server Unique ID;MOTD line 2;Game mode;Game mode (numeric);Port (IPv4);Port (IPv6);
Example:
MCPE;Dedicated Server;390;1.14.60;0;10;13253860892328930865;Bedrock level;Survival;1;19132;19133;
Result:
The Game mode and Game mode (numeric) values seem to not be used by the client.
Connected Ping
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x00 | Time | Long |
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 9 | |
MTU | Zero padding | 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). This padding seems to be used to discover the maximum packet size the network can handle. |
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. According to the official docs, "The MTU size is the maximum size of a packet RakNet will generate", and "if you set the MTU size larger than your or any router along the network path takes, then the network will split the packet at best, or drop it at worst", so this process of sending decreasingly padded packets (compensating for the size of the packet itself and UDP overhead, which together make 48 bytes) seem to be used to discover the maximum packet size the network can handle. See the official documentation page for more info about the MTU size. If the RakNet protocol does not match your own, respond with the Incompatible protocol packet.
You should always respond to the first of these packets that you receive with Offline Connection Response 1, containing an MTU size of the amount of padding you received in bytes plus 46.
Offline Connection Response 1
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x06 | Magic | MAGIC | |
Server GUID | Long | ||
Use security | boolean | Make sure this is false, it is vital for the login sequence to continue! | |
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? | boolean |
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 |
Incompatible protocol
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x19 | Protocol | byte | |
Magic | MAGIC | ||
Server GUID | Long |
Unconnected Ping
Packet ID | Field Name | Field Type | Notes |
---|---|---|---|
0x01, 0x02 | Time | Long | |
GUID | 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 |