Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Minecraft:RakNet: Difference between revisions

From SAS Gaming Wiki
SyncBot (talk | contribs)
Sync: updated from Minecraft
SyncBot (talk | contribs)
Sync: updated from Minecraft
Line 1: Line 1:
{{Exclusive|bedrock}}
{{Exclusive|bedrock}}
'''RakNet'''<ref>http://www.jenkinssoftware.com/</ref> is a networking library used by ''[[Minecraft:Bedrock Edition]]''. This documentation is based on the old [[Minecraft:Pocket Edition protocol|''Pocket Edition'' protocol]] and may be incomplete or outdated.
 
The source code for the RakNet Library can be found [https://github.com/OculusVR/RakNet/ here].
'''RakNet'''<ref>http://www.jenkinssoftware.com/</ref> is a networking library and protocol for multiplayer games. It runs over UDP and provides connection management, configurable reliability and ordering, sequencing, and fragmentation.
RakNet uses {{W|User Datagram Protocol|UDP}} as its networking protocol. The key differences from TCP are that not all packets are guaranteed to reach the destination at all or in order (it isn't reliable) and it uses messages with a specified length instead of streams of data. RakNet compensates for the out-of-order delivery and makes it reliable.
 
UDP does not guarantee delivery or ordering. RakNet supports different delivery modes, so applications can request reliability or ordering when needed.
 
The source code for RakNet is available in the [https://github.com/OculusVR/RakNet/ OculusVR archive].
 
== Use in Bedrock Edition ==
 
In [[Minecraft:Bedrock Edition]], [[Minecraft:NetherNet]] became the default transport for dedicated servers in [[Minecraft:26.50]]. RakNet is deprecated in the [[Minecraft:26.60.22]] Preview.


== Libraries ==
== Libraries ==
'''NOTE:'''
 
You may want to use an existing library if one exists for your language of choice.
Here is an incomplete list of RakNet libraries. Their supported features and protocol versions may differ, so check each project's documentation for compatibility.
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 11 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.


{| class="wikitable sortable" style="width: auto; text-align: center;"
{| class="wikitable sortable" style="width: auto; text-align: center;"
Line 15: Line 21:
  ! Language
  ! Language
  ! License
  ! License
! Active development
  |-
  |-
  ! [https://github.com/sandertv/go-raknet go-raknet]
  ! [https://github.com/sandertv/go-raknet go-raknet]
  | Network System used for [https://github.com/df-mc/dragonfly Dragonfly] written in Go.
  | RakNet implementation used by [https://github.com/df-mc/dragonfly Dragonfly].
  | Golang
  | Go
  | MIT
  | MIT
| Yes
  |-
  |-
  ! [https://github.com/netrexmc/raknet RakNet]
  ! [https://github.com/NetrexMC/RakNet RakNet]
  | RakNet implementation written in Rust.
  | Asynchronous RakNet implementation written in Rust.
  | Rust
  | Rust
  | Apache License
  | Apache-2.0
| No
  |-
  |-
  ! [https://github.com/PieMC-Dev/PieRakNet PieRakNet]
  ! [https://github.com/PieMC-Dev/PieRakNet PieRakNet]
  | Network System used for [https://github.com/PieMC-Dev/PieMC PieMC] written in Python.
  | RakNet implementation written in Python for [https://github.com/PieMC-Dev/PieMC PieMC].
  | Python
  | Python
  | GPL-3
  | GPL-3.0
| Yes
  |-
  |-
  ! [https://github.com/NukkitX/Network NukkitX Network]
  ! [https://github.com/CloudburstMC/Network Cloudburst Network]
  | Network components used within NukkitX, but with great support for general use as well.
  | Network components used by CloudburstMC projects.
  | Java
  | Java
  | Apache License
  | Apache-2.0
| Yes
  |-
  |-
  ! [https://github.com/Podrum/rak_net rak-net]
  ! [https://github.com/Podrum/rak_net rak-net]
  | rak-net is the first updated and fully working RakNet implementation written in Python to run a Minecraft Bedrock Edition server. This library was mainly created for Podrum, although it can be used in other projects too and can be installed via pip.
  | Python RakNet implementation originally developed for Podrum.
  | Python
  | Python
  | GPL
  | GPL-2.0
| No
  |-
  |-
  ! [https://github.com/JRakNet/JRakNet JRakNet]
  ! [https://github.com/whirvis/JRakNet JRakNet]
  | JRakNet is a networking library for Java which implements the UDP based protocol RakNet.
  | Java implementation of the RakNet protocol.
  | Java
  | Java
  | MIT
  | MIT
| No
  |-
  |-
  ! [https://github.com/yesdog/netty-raknet netty-raknet]
  ! [https://github.com/yesdog/netty-raknet netty-raknet]
  | High performance implementation of RakNet for netty, following strict netty patterns.
  | RakNet implementation for Netty.
  | Java
  | Java
  | MIT
  | MIT
| No
  |-
  |-
  ! [https://github.com/jython234/JRakLibPlus JRakLibPlus]
  ! [https://github.com/alejzeis/JRakLibPlus JRakLibPlus]
  | A library for easy creation of RakNet servers, based on RakLib and JRakLib.
  | RakNet server library based on RakLib and JRakLib.
  | Java
  | Java
  | LGPL
  | LGPL
  | No
  |-
|-
  ! [https://github.com/pmmp/RakLib RakLib]
  ! [https://github.com/pmmp/RakLib 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.
  | Lightweight PHP RakNet server implementation.
  | PHP
  | PHP
  | GPL
  | GPL-3.0
  | Yes
  |-
|-
  ! [https://www.npmjs.com/package/raknet/ raknet]
  ! [https://www.npmjs.com/package/raknet/ raknet]
  | UDP network library that follows the RakNet protocol for Node.js.
  | UDP networking library for Node.js that follows the RakNet protocol.
  | Javascript
  | JavaScript
  | MIT
  | MIT
| No
  |-
  |-
  ! [https://pypi.org/project/PyRakLib/ PyRakLib]
  ! [https://pypi.org/project/PyRakLib/ PyRakLib]
  | PyRakLib is a networking library that follows the RakNet protocol for MCPE. It is ported from the PHP library RakLib.  
  | Python port of RakLib that follows the RakNet protocol.
  | Python
  | Python
  | GPL
  | GPL
  | No
  |-
|-
  ! [https://github.com/b23r0/rust-raknet rust-raknet]
  ! [https://github.com/b23r0/rust-raknet rust-raknet]
  | RakNet Protocol implementation by Rust.  
  | RakNet implementation written in Rust.
  | Rust
  | Rust
  | MIT
  | MIT
| No
  |-
  |-
|[https://github.com/SerenityJS/Baltica Baltica]
! [https://github.com/SerenityJS/Baltica Baltica]
|Baltica is a toolkit for Minecraft Bedrock Edition that includes packages for Xbox authentication and RakNet protocol implementation.
| Bedrock toolkit that includes a RakNet implementation.
|TypeScript
| TypeScript
|None
| See repository
|Yes
|-
|-
  ! [https://github.com/mfdgaming/raknet.py RakNet.Py]
  ! [https://github.com/mfdgaming/raknet.py RakNet.Py]
  | Mojang RakNet Protocol version 5 implementation in Python intended for use with MCPE Alpha versions.
  | RakNet protocol version 5 implementation for older MCPE versions.
  | Python
  | Python
  | GPL
  | GPL
| No
  |-
  |-
![https://github.com/LavishMC/LavishRakNet LavishRakNet]
! [https://github.com/LavishMC/RakNet LavishMC RakNet]
|Custom implementation of RakNet made for game client and server.
| C++ fork of the original RakNet implementation.
|C++
|MIT
|Yes
|-
! [https://github.com/facebookarchive/RakNet Raknet] (official)
| The official implementation. Outdated and mostly for reference purposes. May not work with the latest Bedrock.
  | C++
  | C++
  | BSD
  | BSD
  | No
  |-
! [https://github.com/facebookarchive/RakNet RakNet (original)]
| Original C++ RakNet implementation.
| C++
| BSD-2-Clause
  |}
  |}


== Data types ==
== Data types ==
RakNet packet fields use fixed-width integers and a few protocol-specific types. Byte order depends on the field; use the packet definition when encoding or decoding multi-byte values.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/BitStream.h RakNet: BitStream] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet protocol notes]</ref>


{| class="wikitable"
{| class="wikitable"
|-
! Type !! Size !! Description
!
! Size (Bytes)
! Range
! Notes
|-
! byte
| 1
| 0 to 255
|
A single byte, also called uchar or uint8
|-
! Long
| 8
| -2^63 to 2^63-1
| Signed 64-bit Integer, also called int64
|-
! Magic
| 16
| <code>00ffff00fefefefefdfdfdfd12345678</code>
| Always those hex bytes, corresponding to RakNet's default OFFLINE_MESSAGE_DATA_ID
|-
! short
| 2
| -32768 to 32767
| Signed 16-bit integer, also called int16
|-
! unsigned short
| 2
| 0 to 65535
| Unsigned 16-bit integer, also called uint16
|-
! string
| unsigned short + string
| N/A
| class="col3" | Prefixed by a uint16 containing the length of the string in characters, encoded in network byte order (see below). It appears that only the following ASCII characters can be displayed: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|-
! boolean
| 1
| 0 to 1
| True is encoded as <code>0x01</code>, false as <code>0x00</code>.
|-
! address
| 7 or 29
| N/A
| class="col3" |If the address is IPv4:
{| class="wikitable"
!Field
!Type
!Endianness
!Value
|-
|-
|Family
! Byte
|byte
| 1 byte
|Little-endian
| Unsigned 8-bit value.
|0x4
|-
|-
|IP Bytes
! Boolean
|byte[4]
| 1 byte
|Big-endian
| <code>0x00</code> is false; <code>0x01</code> is true.
|''variable''
|-
|-
|Port
! Short
|uint16
| 2 bytes
|Big-endian
| Signed 16-bit integer.
|''variable''
|}
Else, if the address is IPv6:
{| class="wikitable"
!Field
!Type
!Endianness
!Value
|-
|-
|Family
! Unsigned Short
|byte
| 2 bytes
|Little-endian
| Unsigned 16-bit integer.
|0x6
|-
|-
|Address Family
! Int
|uint16
| 4 bytes
|Little-endian
| Signed 32-bit integer.
|0x23 seems to work
|-
|-
|Port
! Long
|uint16
| 8 bytes
|Big-endian
| 64-bit integer. Whether it represents a signed value depends on the field.
|''variable''
|-
|-
|Flow Info
! uint24le
|uint32
| 3 bytes
|Big-endian
| Unsigned 24-bit little-endian integer, used for frame sequence numbers.
|0x0 seems to work
|-
|-
|IP Bytes
! String
|byte[16]
| Variable
|Big-endian
| In RakNet string fields, an unsigned 16-bit length precedes the string bytes.
|''variable''
|-
|-
|Scope ID
! Magic
|uint32
| 16 bytes
|Big-endian
| The fixed <code>00ffff00fefefefefdfdfdfd12345678</code> value used in offline packets.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp RakNet: RakPeer.cpp]</ref>
|0x0 seems to work
|}
''Note: The IPv4 format is 7 bytes long, IPv6 is 29 bytes long.''
|-
! uint24le
| 3
| 0 to 16,777,215
| 3-byte little-endian unsigned integer
|-
|-
! Int
! Address
| 4
| 7 bytes (IPv4); 29 bytes (IPv6)
| -2147483648 to 2147483647
| Encodes the address family, address and port. IPv4 address bytes are inverted; the port is big-endian. IPv6 also includes address-family, flow-info and scope fields.<ref name="address-format">[https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet address format]</ref>
| Signed little-endian 32-bit Integer, also called int32
|}
|}
''Note that some types and fields are encoded in network byte order (big-endian, see [[Minecraft:w:Endianness#Networking|wikipedia]]), and decoding them in the wrong way could cause unexpected behaviour.''


== Handshake sequence ==
== Handshake sequence ==
RakNet establishes a peer connection first, then completes the connection with the application.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp RakNet: RakPeer.cpp] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet connection sequence]</ref>


# C→S: [[#Open Connection Request 1|Open Connection Request 1]]
# C→S: [[#Open Connection Request 1|Open Connection Request 1]]
# S→C: [[#Open Connection Reply 1|Open Connection Reply 1]]
# S→C: [[#Open Connection Reply 1|Open Connection Reply 1]] (or [[#Incompatible Protocol|Incompatible Protocol]])
# C→S: [[#Open Connection Request 2|Open Connection Request 2]]
# C→S: [[#Open Connection Request 2|Open Connection Request 2]]
# S→C: [[#Open Connection Reply 2|Open Connection Reply 2]]
# S→C: [[#Open Connection Reply 2|Open Connection Reply 2]]. The RakNet peer connection is established.
 
From here on, the RakNet connection is established and all RakNet messages are contained in a [[#Frame Set Packet|Frame Set Packet]].
 
# C→S: [[#Connection Request|Connection Request]]
# C→S: [[#Connection Request|Connection Request]]
# S→C: [[#Connection Request Accepted|Connection Request Accepted]]
# S→C: [[#Connection Request Accepted|Connection Request Accepted]]
# C→S: [[#New Incoming Connection|New Incoming Connection]]
# C→S: [[#New Incoming Connection|New Incoming Connection]]


Next packets should be [[#Game Packet|Game Packets]].
After this exchange, peers can send connected packets. In Bedrock Edition, game packets are carried in RakNet frames as described at [[#Game Packet|Game Packet]].


== Packets ==
== Packets ==
Packet identifiers below follow the standard RakNet packet IDs. Some field details vary by implementation.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/MessageIdentifiers.h RakNet: Message identifiers] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet protocol notes]</ref>


=== Unconnected Ping ===
=== Unconnected Ping ===
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 276: Line 191:
  |}
  |}


This is the first RakNet message sent by the client to a RakNet server. <code>0x01</code> is sent almost every second if the client is on the server list menu and every 4-5 seconds if the client is in-game.
The client sends this packet to discover a server. ID <code>0x01</code> is a regular unconnected ping; <code>0x02</code> asks for a response only when the server has open connections. The server replies with [[#Unconnected Pong|Unconnected Pong]].
<code>0x02</code> 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.<br>
This packet should be responded to with unconnected Pong.


=== Unconnected Pong ===
=== Unconnected Pong ===
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 302: Line 216:
  | Server ID String
  | Server ID String
  | string
  | string
  | Used for the MOTD. See below for details.
  | Carries server-list information.
  |}
  |}


Unconnected Pong message is sent by the server to the client in response to the Unconnected Ping message. ''Time'' shall be set to the time received in the [[#Unconnected Ping|Unconnected Ping]] as it will probably be used to calculate ping. The ''Server ID String'' contains various data that is sent to the client such as MOTD, number of players, max player count, etc. The format is given below:
The server sends this in response to an unconnected ping. It echoes the ping time and includes its GUID and a server ID string. In [[Minecraft:Bedrock Edition]], that string contains server-list information in a semicolon-delimited format; its fields can vary by game version.
 
'''Server ID string format'''
 
For Minecraft Bedrock this is separated by semicolons and uses the following format:<br>
<code>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);</code><br>
Example:<br>
<code>MCPE;Dedicated Server;390;1.14.60;0;10;13253860892328930865;Bedrock level;Survival;1;19132;19133;</code><br>
Result:<br>
[[File:Server ID_String Example.png]]
 
The Game mode and Game mode (numeric) values seem to not be used by the client.


=== Connected Ping ===
=== Connected Ping ===
Line 332: Line 235:
  |}
  |}


This is the first packet sent in the Encapsulated Frame Set Packet by the client to the server. It is sent with the reliability type Unreliable so it can be handled immediately by the server.
This packet measures latency on an established connection. It is commonly sent unreliably.
It is used for calculating the average ping between the client and the server.


=== Connected Pong ===
=== Connected Pong ===
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 352: Line 255:
  |}
  |}


Connected Pong message is sent in response to the Connected Ping message with reliability type set to Unreliable so it can be handled immediately by the client.
The receiver replies with the original ping time and its own response time. It is commonly sent unreliably.


=== Open Connection Request 1 ===
=== Open Connection Request 1 ===
The first packet in the handshake sequence, sent by the client to the server.
The first packet in the handshake sequence, sent by the client to the server.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 369: Line 274:
  | Protocol version
  | Protocol version
  | byte
  | byte
  | Currently 11
  | RakNet protocol version used by the client.
  |-
  |-
  | MTU
  | MTU
  | Zero padding
  | 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.
  | Zero padding used to probe the path MTU.
  |}
  |}


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 46 bytes) seem to be used to discover the maximum packet size the network can handle. See the [http://www.jenkinssoftware.com/raknet/manual/programmingtips.html 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.<br><br>
The padding is used to probe the path MTU. The server replies with the selected MTU, or sends [[#Incompatible Protocol|Incompatible Protocol]] if it does not support the client's RakNet protocol version.
You should always respond to the first of these packets that you receive with Open Connection Reply 1, containing an MTU size of the amount of padding you received in bytes plus 46.


=== Open Connection Reply 1 ===
=== Open Connection Reply 1 ===
The second packet in the handshake sequence, sent by the server to the client.
The second packet in the handshake sequence, sent by the server to the client.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 398: Line 304:
  | Use security
  | Use security
  | boolean
  | boolean
  | If true, a cookie can be specified after to prevent source IP spoofing
  | Indicates whether the server is using RakNet's security challenge.
  |-
  |-
  | Cookie
  | Cookie
  | Int
  | Int
  | Only if use security; a cookie to be sent back by the client in Open Connection Request 2
  | Present only when security is enabled; returned by the client in Open Connection Request 2.
  |-
  |-
  | MTU
  | MTU
  | Unsigned short
  | Unsigned short
  | see Open Connection Request 1
  | Selected MTU for the connection.
  |}
  |}


=== Open Connection Request 2 ===
=== Open Connection Request 2 ===
The third packet in the handshake sequence, sent by the client to the server.
The third packet in the handshake sequence, sent by the client to the server.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 421: Line 329:
  | MAGIC
  | MAGIC
  |  
  |  
   
  |-
|-
  | Cookie
  | Cookie
  | Int
  | Int
  | Only present if a cookie was provided by the server in Open Connection Reply 1
  | Present only when the server provided a cookie.
  |-
  |-
  | Has security challenge
  | Has security challenge
  | boolean
  | boolean
  | Only present if a cookie was provided by the server in Open Connection Reply 1
  | Sent with the cookie when security is enabled.
  |-
  |-
  | Server Address
  | Server Address
  | address
  | address
  |  
  |  
   
  |-
|-
  | MTU
  | MTU
  | short
  | Unsigned Short
  |  
  |  
   
  |-
|-
  | Client GUID
  | Client GUID
  | Long
  | Long
Line 447: Line 352:


=== Open Connection Reply 2 ===
=== Open Connection Reply 2 ===
The fourth packet in the handshake sequence, sent by the server to the client.
The fourth packet in the handshake sequence, sent by the server to the client.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 468: Line 375:
  |-
  |-
  | MTU
  | MTU
  | short
  | Unsigned Short
  |  
  |  
  |-
  |-
Line 477: Line 384:


=== Connection Request ===
=== Connection Request ===
The client sends this packet after the RakNet peer connection is established to request an application-level connection.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 498: Line 408:


=== Connection Request Accepted ===
=== Connection Request Accepted ===
The server sends this packet to accept the client's connection request.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 510: Line 423:
  |-
  |-
  | System index
  | System index
  | short
  | Unsigned Short
  | Unknown what this does. 0 works as a value.
  | System index assigned by the server.
  |-
  |-
  | Internal IDs
  | Internal addresses
  | 10x address
  | 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.
  | Internal server addresses.
  |-
  |-
  | Request time
  | Request time
Line 523: Line 436:
  | Time
  | Time
  | Long
  | Long
  | Current send time in milliseconds
  | Server acceptance time.
  |}
  |}


=== New Incoming Connection ===
=== New Incoming Connection ===
The client sends this packet to confirm that it received the server's acceptance.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 538: Line 454:
  |  
  |  
  |-
  |-
  | Internal address
  | Internal addresses
  | 20x address
  | 20x address
  | Unknown what this is used for.
  | Internal client addresses.
|-
  |-
  |-
  | Incoming Timestamp
  | Incoming Timestamp
  | Long
  | Long
  |  
  |  
|-
  |-
  |-
  | Server Timestamp
  | Server Timestamp
Line 554: Line 468:
  |}
  |}


=== Disconnect ===
=== Disconnection Notification ===
 
This packet notifies the other peer that the sender is disconnecting
 
{| class="wikitable"
{| class="wikitable"
! Packet ID
! Packet ID !! Field Name !! Field Type !! Notes
|-
|-
|0x15
| 0x15 || colspan="2" | No payload || Signals that the sender is disconnecting.
|-
|}
|}


=== Incompatible Protocol ===
=== Incompatible Protocol ===
The server sends this packet when it does not support the RakNet protocol version used by the client.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 584: Line 503:
  |}
  |}


=== Unconnected Ping ===
{| class="wikitable"
! Packet ID
! Field Name
! Field Type
! Notes
|-
|rowspan="2"| 0x01, 0x02
| Time
| Long
|
|-
| GUID
| Long
|
|}


=== Frame Set Packet ===
=== Frame Set Packet ===
This packet carries one or more frames between connected peers.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 641: Line 547:
  |rowspan="3"| Fragment<br>(only if fragmented)
  |rowspan="3"| Fragment<br>(only if fragmented)
  | Compound size
  | Compound size
  | int
  | Unsigned Int
  | Total size of the compound
  | Total size of the compound
  |-
  |-
  | Compound ID
  | Compound ID
  | short
  | Unsigned Short
  | Identifies which compound this fragment is part of
  | Identifies which compound this fragment is part of
  |-
  |-
  | Index
  | Index
  | int
  | Unsigned Int
  | Index of this fragment in the compound
  | Index of this fragment in the compound
  |-
  |-
Line 659: Line 565:


'''Note 1: there can be multiple frames in each Frame Set Packet.'''<br>
'''Note 1: there can be multiple frames in each Frame Set Packet.'''<br>
'''Note 2: A packet is a Frame Set Packet if <code>(packet_ID & 0x80) == 0x80</code> and <code>(packet_ID & 0x60) == 0</code>'''<br>
'''Note 2: A packet is a Frame Set Packet if <code>(packet_ID & 0x80) == 0x80</code> and <code>(packet_ID & 0x60) == 0</code>'''
<br>
 
The reliability types are as follows:
The reliability types are as follows:


Line 667: Line 573:
! style="font-weight: bold;" | Name
! style="font-weight: bold;" | Name
! style="text-align: center; font-weight: bold;" | Reliable
! style="text-align: center; font-weight: bold;" | Reliable
! style="text-align: center; font-weight: bold;" | Sequenced
! style="text-align: center; font-weight: bold;" | Ordered
! style="text-align: center; font-weight: bold;" | Ordered
! style="text-align: center; font-weight: bold;" | Sequenced
|-
|-
| style="text-align: center;" | 0
| style="text-align: center;" | 0
Line 680: Line 586:
| style="text-align: center;" |  
| style="text-align: center;" |  
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |  
|-
|-
| style="text-align: center;" | 2
| style="text-align: center;" | 2
Line 691: Line 597:
| reliable ordered
| reliable ordered
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |
|-
|-
| style="text-align: center;" | 4
| style="text-align: center;" | 4
Line 698: Line 604:
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |  
|-
|-
| style="text-align: center;" | 5
| style="text-align: center;" | 5
Line 715: Line 621:
| reliable ordered (+ ACK receipt)
| reliable ordered (+ ACK receipt)
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |
| style="text-align: center;" | x
| style="text-align: center;" | x
| style="text-align: center;" |
|}
|}


Sequenced implies ordered.
Sequenced delivery discards older packets when a newer packet has arrived. Ordered delivery preserves the order of reliable packets within a channel.


=== Game Packet ===
=== Game Packet ===
This packet carries game-protocol data. In [[Minecraft:Bedrock Edition]], its body contains a batch of game packets.
{| class="wikitable"
{| class="wikitable"
  ! Packet ID
  ! Packet ID
Line 731: Line 640:
  | Body
  | Body
  | bytes
  | bytes
  | Single packet of the GAME protocol. The packet is usually compressed.
  | In [[Minecraft:Bedrock Edition]], the body contains a batch of game packets. Framing and compression are described in [[Minecraft:Bedrock Edition protocol#Packet Format|Bedrock Edition protocol]].
  |}
  |}
In [[Minecraft:Bedrock Edition|Minecraft Bedrock Edition]], the game packet contains bytes encoded according to the [[Minecraft:Bedrock Edition protocol|Bedrock Edition Protocol]].
In [[Minecraft:Bedrock Edition]], the body carries a batch of game packets encoded according to the [[Minecraft:Bedrock Edition protocol]]. See [[Minecraft:Bedrock_Edition_protocol/Packets|Bedrock Edition protocol/Packets]] for their definitions.


=== NACK ===
=== NACK ===
This packet reports [[Minecraft:wikipedia:User_Datagram_Protocol|datagrams]] that were not received so the sender can retransmit them when required.
{| class="wikitable"
{| class="wikitable"
! style="font-weight: bold;" | Packet ID
! style="font-weight: bold;" | Packet ID
Line 744: Line 656:
| rowspan="5" | 0xa0
| rowspan="5" | 0xa0
| colspan="3" | Record count
| colspan="3" | Record count
| short
| Unsigned Short
| Number of records in the packet
| Number of records in the packet
|-
|-
Line 755: Line 667:
| Sequence number
| Sequence number
| uint24le
| uint24le
| Sequence number to acknowledge
| Datagram sequence number in this record.
|-
|-
| rowspan="2" | Range, if <code>is_single == false</code>
| rowspan="2" | Range, if <code>is_single == false</code>
| Start Sequence number
| Start Sequence number
| uint24le
| uint24le
|Beginning of the range
|First datagram sequence number in the range.
|-
|-
| End Sequence number
| End Sequence number
| uint24le
| uint24le
|End of the range
|Last datagram sequence number in the range.
|}
|}
A NACK is sent by either the client or the server periodically to request packets that were not received. They are sent back only if they were marked with reliable (see [[#Frame Set Packet|Frame Set Packet]]).
A NACK reports frame-set sequence numbers that were not received, prompting retransmission where required.


=== ACK ===
=== ACK ===
This packet acknowledges [[Minecraft:wikipedia:User_Datagram_Protocol|datagrams]] received from the other peer.
{| class="wikitable"
{| class="wikitable"
! style="font-weight: bold;" | Packet ID
! style="font-weight: bold;" | Packet ID
Line 777: Line 692:
| rowspan="5" | 0xc0
| rowspan="5" | 0xc0
| colspan="3" | Record count
| colspan="3" | Record count
| short
| Unsigned Short
| Number of records in the packet
| Number of records in the packet
|-
|-
Line 788: Line 703:
| Sequence number
| Sequence number
| uint24le
| uint24le
| Sequence number to acknowledge
| Datagram sequence number in this record.
|-
|-
| rowspan="2" | Range, if <code>is_single == false</code>
| rowspan="2" | Range, if <code>is_single == false</code>
| Start Sequence number
| Start Sequence number
| uint24le
| uint24le
|Beginning of the range
|First datagram sequence number in the range.
|-
|-
| End Sequence number
| End Sequence number
| uint24le
| uint24le
|End of the range
|Last datagram sequence number in the range.
|}
|}
An ACK should be sent periodically to acknowledge every packet that was received.<br>
An ACK reports frame-set sequence numbers that were received. Both ACK and NACK packets can contain multiple records.
<br>
'''Note: for both ACK and NACK packets, there can be multiple records.'''


== References ==
== References ==
Line 810: Line 723:


[[Category:Bedrock Edition]]
[[Category:Bedrock Edition]]
{{license wiki.vg}}
[[Minecraft:ru:RakNet]]

Revision as of 11:21, 3 October 2026

Template:Exclusive

RakNet<ref>http://www.jenkinssoftware.com/</ref> is a networking library and protocol for multiplayer games. It runs over UDP and provides connection management, configurable reliability and ordering, sequencing, and fragmentation.

UDP does not guarantee delivery or ordering. RakNet supports different delivery modes, so applications can request reliability or ordering when needed.

The source code for RakNet is available in the OculusVR archive.

Use in Bedrock Edition

In Minecraft:Bedrock Edition, Minecraft:NetherNet became the default transport for dedicated servers in Minecraft:26.50. RakNet is deprecated in the Minecraft:26.60.22 Preview.

Libraries

Here is an incomplete list of RakNet libraries. Their supported features and protocol versions may differ, so check each project's documentation for compatibility.

Name Description Language License
go-raknet RakNet implementation used by Dragonfly. Go MIT
RakNet Asynchronous RakNet implementation written in Rust. Rust Apache-2.0
PieRakNet RakNet implementation written in Python for PieMC. Python GPL-3.0
Cloudburst Network Network components used by CloudburstMC projects. Java Apache-2.0
rak-net Python RakNet implementation originally developed for Podrum. Python GPL-2.0
JRakNet Java implementation of the RakNet protocol. Java MIT
netty-raknet RakNet implementation for Netty. Java MIT
JRakLibPlus RakNet server library based on RakLib and JRakLib. Java LGPL
RakLib Lightweight PHP RakNet server implementation. PHP GPL-3.0
raknet UDP networking library for Node.js that follows the RakNet protocol. JavaScript MIT
PyRakLib Python port of RakLib that follows the RakNet protocol. Python GPL
rust-raknet RakNet implementation written in Rust. Rust MIT
Baltica Bedrock toolkit that includes a RakNet implementation. TypeScript See repository
RakNet.Py RakNet protocol version 5 implementation for older MCPE versions. Python GPL
LavishMC RakNet C++ fork of the original RakNet implementation. C++ BSD
RakNet (original) Original C++ RakNet implementation. C++ BSD-2-Clause

Data types

RakNet packet fields use fixed-width integers and a few protocol-specific types. Byte order depends on the field; use the packet definition when encoding or decoding multi-byte values.<ref>RakNet: BitStream GolemOrg: RakNet protocol notes</ref>

Type Size Description
Byte 1 byte Unsigned 8-bit value.
Boolean 1 byte 0x00 is false; 0x01 is true.
Short 2 bytes Signed 16-bit integer.
Unsigned Short 2 bytes Unsigned 16-bit integer.
Int 4 bytes Signed 32-bit integer.
Long 8 bytes 64-bit integer. Whether it represents a signed value depends on the field.
uint24le 3 bytes Unsigned 24-bit little-endian integer, used for frame sequence numbers.
String Variable In RakNet string fields, an unsigned 16-bit length precedes the string bytes.
Magic 16 bytes The fixed 00ffff00fefefefefdfdfdfd12345678 value used in offline packets.<ref>RakNet: RakPeer.cpp</ref>
Address 7 bytes (IPv4); 29 bytes (IPv6) Encodes the address family, address and port. IPv4 address bytes are inverted; the port is big-endian. IPv6 also includes address-family, flow-info and scope fields.<ref name="address-format">GolemOrg: RakNet address format</ref>

Handshake sequence

RakNet establishes a peer connection first, then completes the connection with the application.<ref>RakNet: RakPeer.cpp GolemOrg: RakNet connection sequence</ref>

  1. C→S: Open Connection Request 1
  2. S→C: Open Connection Reply 1 (or Incompatible Protocol)
  3. C→S: Open Connection Request 2
  4. S→C: Open Connection Reply 2. The RakNet peer connection is established.
  5. C→S: Connection Request
  6. S→C: Connection Request Accepted
  7. C→S: New Incoming Connection

After this exchange, peers can send connected packets. In Bedrock Edition, game packets are carried in RakNet frames as described at Game Packet.

Packets

Packet identifiers below follow the standard RakNet packet IDs. Some field details vary by implementation.<ref>RakNet: Message identifiers GolemOrg: RakNet protocol notes</ref>

Unconnected Ping

Packet ID Field Name Field Type Notes
0x01, 0x02 Time Long
MAGIC magic
Client GUID Long

The client sends this packet to discover a server. ID 0x01 is a regular unconnected ping; 0x02 asks for a response only when the server has open connections. The server replies with Unconnected Pong.

Unconnected Pong

Packet ID Field Name Field Type Notes
0x1c Time Long
Server GUID Long
MAGIC magic
Server ID String string Carries server-list information.

The server sends this in response to an unconnected ping. It echoes the ping time and includes its GUID and a server ID string. In Minecraft:Bedrock Edition, that string contains server-list information in a semicolon-delimited format; its fields can vary by game version.

Connected Ping

Packet ID Field Name Field Type Notes
0x00 Time Long

This packet measures latency on an established connection. It is commonly sent unreliably.

Connected Pong

Packet ID Field Name Field Type Notes
0x03 Ping Time Long
Pong Time Long

The receiver replies with the original ping time and its own response time. It is commonly sent unreliably.

Open Connection Request 1

The first packet in the handshake sequence, sent by the client to the server.

Packet ID Field Name Field Type Notes
0x05 Magic MAGIC
Protocol version byte RakNet protocol version used by the client.
MTU Zero padding Zero padding used to probe the path MTU.

The padding is used to probe the path MTU. The server replies with the selected MTU, or sends Incompatible Protocol if it does not support the client's RakNet protocol version.

Open Connection Reply 1

The second packet in the handshake sequence, sent by the server to the client.

Packet ID Field Name Field Type Notes
0x06 Magic MAGIC
Server GUID Long
Use security boolean Indicates whether the server is using RakNet's security challenge.
Cookie Int Present only when security is enabled; returned by the client in Open Connection Request 2.
MTU Unsigned short Selected MTU for the connection.

Open Connection Request 2

The third packet in the handshake sequence, sent by the client to the server.

Packet ID Field Name Field Type Notes
0x07 Magic MAGIC
Cookie Int Present only when the server provided a cookie.
Has security challenge boolean Sent with the cookie when security is enabled.
Server Address address
MTU Unsigned Short
Client GUID Long

Open Connection Reply 2

The fourth packet in the handshake sequence, sent by the server to the client.

Packet ID Field Name Field Type Notes
0x08 Magic MAGIC
Server GUID Long
Client Address address
MTU Unsigned Short
Encryption enabled boolean

Connection Request

The client sends this packet after the RakNet peer connection is established to request an application-level connection.

Packet ID Field Name Field Type Notes
0x09 GUID Long
Time Long
Use security boolean

Connection Request Accepted

The server sends this packet to accept the client's connection request.

Packet ID Field Name Field Type Notes
0x10 Client address address
System index Unsigned Short System index assigned by the server.
Internal addresses 10x address Internal server addresses.
Request time Long Shall be the corresponding timestamp of the Connection Request
Time Long Server acceptance time.

New Incoming Connection

The client sends this packet to confirm that it received the server's acceptance.

Packet ID Field Name Field Type Notes
0x13 Server address address
Internal addresses 20x address Internal client addresses.
Incoming Timestamp Long
Server Timestamp Long

Disconnection Notification

This packet notifies the other peer that the sender is disconnecting

Packet ID Field Name Field Type Notes
0x15 No payload Signals that the sender is disconnecting.

Incompatible Protocol

The server sends this packet when it does not support the RakNet protocol version used by the client.

Packet ID Field Name Field Type Notes
0x19 Protocol byte
Magic MAGIC
Server GUID Long


Frame Set Packet

This packet carries one or more frames between connected peers.

Packet ID Field Name Field Type Notes
0x80..0x8d Sequence number uint24le Used for building ACK and NACK ranges
Frames Flags byte Top 3 bits give the reliability type, fourth bit is 1 when the frame is fragmented and part of a compound.
Length IN BITS unsigned short Length of the body in bits. Big-endian.
Reliable frame index uint24le Only if reliable, used for detecting frame level duplication
Sequenced frame index uint24le Only if sequenced, used for discarding out-of-date packets
Order
(only if ordered, see
below)
Ordered frame index uint24le Tells the receiver the correct order in which to deliver frames to the application
Order channel byte Maximum of 32 channels
Fragment
(only if fragmented)
Compound size Unsigned Int Total size of the compound
Compound ID Unsigned Short Identifies which compound this fragment is part of
Index Unsigned Int Index of this fragment in the compound
Body ceil(length/8) bytes

Note 1: there can be multiple frames in each Frame Set Packet.
Note 2: A packet is a Frame Set Packet if (packet_ID & 0x80) == 0x80 and (packet_ID & 0x60) == 0

The reliability types are as follows:

ID Name Reliable Sequenced Ordered
0 unreliable
1 unreliable sequenced x
2 reliable x
3 reliable ordered x x
4 reliable sequenced x x
5 unreliable (+ ACK receipt)
6 reliable (+ ACK receipt) x
7 reliable ordered (+ ACK receipt) x x

Sequenced delivery discards older packets when a newer packet has arrived. Ordered delivery preserves the order of reliable packets within a channel.

Game Packet

This packet carries game-protocol data. In Minecraft:Bedrock Edition, its body contains a batch of game packets.

Packet ID Field Name Field Type Notes
0xfe Body bytes In Minecraft:Bedrock Edition, the body contains a batch of game packets. Framing and compression are described in Bedrock Edition protocol.

In Minecraft:Bedrock Edition, the body carries a batch of game packets encoded according to the Minecraft:Bedrock Edition protocol. See Bedrock Edition protocol/Packets for their definitions.

NACK

This packet reports datagrams that were not received so the sender can retransmit them when required.

Packet ID Field Name Field Type Notes
0xa0 Record count Unsigned Short Number of records in the packet
Records Is Single? boolean False for range, True for no range
No Range, if is_single == true Sequence number uint24le Datagram sequence number in this record.
Range, if is_single == false Start Sequence number uint24le First datagram sequence number in the range.
End Sequence number uint24le Last datagram sequence number in the range.

A NACK reports frame-set sequence numbers that were not received, prompting retransmission where required.

ACK

This packet acknowledges datagrams received from the other peer.

Packet ID Field Name Field Type Notes
0xc0 Record count Unsigned Short Number of records in the packet
Records Is Single? boolean False for range, True for no range
No Range, if is_single == true Sequence number uint24le Datagram sequence number in this record.
Range, if is_single == false Start Sequence number uint24le First datagram sequence number in the range.
End Sequence number uint24le Last datagram sequence number in the range.

An ACK reports frame-set sequence numbers that were received. Both ACK and NACK packets can contain multiple records.

References

Template:Reflist

Navigation

Template:Navbox Bedrock Edition