Repository navigation
Expand file tree
/
Copy pathprotocol.tex
More file actions
140 lines (103 loc) · 6.87 KB
/
Copy pathprotocol.tex
File metadata and controls
140 lines (103 loc) · 6.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
\chapter{Protocol}\label{chap:protocol}
\section{Custom data types}\label{sec:protocol-types}
Unlike the Raknet protocol, every number used in the Bedrock protocol is in little endian format.
Besides the standard integer types, the protocol uses the following custom types:
\begin{enumerate}
\item \textit{Variable size integers} - The majority of numbers in the protocol are represented using variable size integers.
As the name suggests, these can grow when needed.
There are a few different types: varuint32, varint32, varuint64 and varint64.
\item \textit{String} - Unlike Raknet's String type, Minecraft prefixes the string data with a varuint32.
\item
\end{enumerate}
\section{Header}\label{sec:protocol-header}
Every protocol packet is preceded by a header containing info about the packet.
This header contains the ID of the packet and the sender/target subclients.
The client or server can specify a subclient in order to send a packet to a specific player during split screen play.
Usually these IDs are set to 0 when there is no split screen.
The complete header is encoded in a single varuint32.
The first 10 bytes are the packet ID, the next 2 the sender and the last 2 are the target.
\section{Packets}\label{sec:protocol-packets}
\subsection{Request Network Settings}\label{subsec:request-network-settings}
Sent by the client to request network settings.
This is the first protocol packet sent by the client and is required in order to enable compression.
\packet{request-network-settings}{Request Network Settings (0xc1)}{
Protocol version & uint32le & The version of the Minecraft protocol. \\
}
In case of an incompatible protocol version, a Play Status (\ref{subsec:play-status}) packet with a status of
FailedClient or FailedServer should be sent.
\subsection{Network Settings}\label{subsec:network-settings}
The network settings packet is sent in response to Request Network Settings (\ref{subsec:request-network-settings}) to tell
the client about the settings the server is using.
\packet{network-settings}{Network Settings (0x8f)}{
Compression threshold & uint16le & Maximum allowed size of a packet before it should be compressed.
This can be set to 0 to disable compression or to 1 to enable compression for all packets regardless of size. \\
\hline
Compression algorithm & uint16le & The compression algorithm to use for packet compression.
Minecraft currently supports two algorithms: A value of 0 for Deflate and 1 for Snappy. \\
\hline
Throttling enabled & boolean & Enabling this allows the client to tick fewer players, improving performance. \\
\hline
Throttle threshold & uint8 & Minimum amount of players required before starting to throttle. \\
\hline
Throttle scalar & f32le & Strength of the throttling. This is probably a scale from 0.0 to 1.0? \\
}
\subsection{Login}\label{subsec:login}
The first packet sent by the client after initiating the Raknet connection is the Login packet.
It contains most of the information that uniquely identifies each player.
\packet{login}{Login (0x01)}{
Protocol version & uint32be & The version of the Minecraft protocol. This has been replaced by the one in Request Network Settings (\ref{subsec:request-network-settings}) \\
\hline
Chain data & String & The chain is a JSON-encoded array of 1 or 3 JSON web tokens. More info below. \\
\hline
User data & String & A self-signed JSON web token containing info such as the user's skin. \\
}
\subsubsection{Login chain}\label{subsubsec:login-chain}
The chain is a JSON-encoded array of one or three JSON web tokens.
If the user is not authenticated with Microsoft services, this chain contains one token.
It however seems that this case never occurs because Minecraft now requires an Xbox account to join servers.
In case of three tokens, the first token contains a public key in the x5u header.
This public key should be used to verify the token's signature.
It contains an identityPublicKey field which gives the public key of the second token in the chain.
As the second token is signed by Mojang in order to prevent tampering,
this token's public key should be equal to Mojang's public key: \\
\noindent
\texttt{MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83\\ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuK\\dm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V}
\\
\noindent
This token holds another \texttt{identityPublicKey} field that contains the public key for the third token.
The third token contains an \texttt{extraData} field, that holds the client's identity data,
such as the \texttt{XUID}, \texttt{identity} and \texttt{displayName}.
Besides the identity data, there is once again an identityPublicKey field that contains the client's actual public key.
\subsubsection{User data}\label{subsubsec:user-data}
The user data token is the largest of the four and contains mostly misc settings and the client's skin.
There is too much information to include it in this document. The token can easily be decoded by viewing it on a site like \url{https://jwt.io}.
This token is self-signed and should therefore not be seen as secure.
\subsection{Play Status}\label{subsec:play-status}
The Play Status packet is sent by the server to notify the client about a login status update.
\packet{play-status}{Play Status (0x02)}{
Status & uint32be & The current status of the connection. \\
}
There are a few different statuses
\begin{itemize}
\item \textit{LoginSuccess} \\
Sent by the server to tell the client about a successful login. This is generally sent after succesfully decrypting an encrypted Client to Server Handshake (\ref{subsec:client-to-server-handshake}) packet.
\item \textit{FailedClient} \\
This status should be sent when the client is running an older version of the game than the server.
It displays "Could not connect: Outdated Client!"
\item \textit{FailedServer} \\
This status should be sent when the server is running an older version fo the game than the client.
It displays "Could not connect: Outdated Server!"
\item \textit{PlayerSpawn} \\
Sent at the end of the login sequence to make the player physically spawn in-game.
\item \textit{FailedInvalidTenant} \\
Displays "Unable to connect. You do not have access to this world."
\item \textit{FailedVanillaEdu} \\
Displays "The server is not running Minecraft: Education Edition. Failed to connect."
\item \textit{FailedIncompatible} \\
Displays "The server is running an incompatible edition of Minecraft. Failed to connect."
\item \textit{FailedServerFull} \\
Displays "Wow this server is popular! Check back later to see if space opens up. Server Full."
\item \textit{FailedEditorToVanillaMismatch} \\
Displays "The server is not in editor mode. Failed to connect."
\end{itemize}
\section{Skin format}\label{sec:protocol-skin}