https://wiki.vg/api.php?action=feedcontributions&user=Drainedsoul&feedformat=atomwiki.vg - User contributions [en]2024-03-29T00:11:27ZUser contributionsMediaWiki 1.34.4https://wiki.vg/index.php?title=Data_types&diff=8461Data types2017-04-02T00:39:13Z<p>Drainedsoul: long long from C is not guaranteed to be 64 bits</p>
<hr />
<div><noinclude>This article defines the '''data types''' used in the [[protocol]]. </noinclude>All data sent over the network (except for VarInt and VarLong) is [[wikipedia:Endianness#Big-endian|big-endian]], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<noinclude><br />
== Definitions ==<br />
</noinclude><br />
{| class="wikitable"<br />
|-<br />
! Name<br />
! Size (bytes)<br />
! Encodes<br />
! Notes<br />
|-<br />
! Boolean<br />
| 1<br />
| Either false or true<br />
| True is encoded as <code>0x01</code>, false as <code>0x00</code>.<br />
|-<br />
! Byte<br />
| 1<br />
| An integer between -128 and 127<br />
| Signed 8-bit integer, [[wikipedia:Two's complement|two's complement]]<br />
|-<br />
! Unsigned Byte<br />
| 1<br />
| An integer between 0 and 255<br />
| Unsigned 8-bit integer<br />
|-<br />
! Short<br />
| 2<br />
| An integer between -32768 and 32767<br />
| Signed 16-bit integer, two's complement<br />
|-<br />
! Unsigned Short<br />
| 2<br />
| An integer between 0 and 65535<br />
| Unsigned 16-bit integer<br />
|-<br />
! Int<br />
| 4<br />
| An integer between -2147483648 and 2147483647<br />
| Signed 32-bit integer, two's complement<br />
|-<br />
! Long<br />
| 8<br />
| An integer between -9223372036854775808 and 9223372036854775807<br />
| Signed 64-bit integer, two's complement<br />
|-<br />
! Float<br />
| 4<br />
| A [[wikipedia:Single-precision floating-point format|single-precision 32-bit IEEE 754 floating point number]]<br />
| <br />
|-<br />
! Double<br />
| 8<br />
| A [[wikipedia:Double-precision floating-point format|double-precision 64-bit IEEE 754 floating point number]]<br />
| <br />
|-<br />
! String (n)<br />
| ≥ 1 <br />≤ (n&times;4) + 3<br />
| A sequence of [[wikipedia:Unicode|Unicode]] [http://unicode.org/glossary/#unicode_scalar_value scalar values]<br />
| [[wikipedia:UTF-8|UTF-8]] string prefixed with its size in bytes as a VarInt. Maximum length of <code>n</code> characters, which varies by context; up to <code>n &times; 4</code> bytes can be used to encode <code>n</code> characters and both of those limits are checked. Maximum <code>n</code> value is 32767. The + 3 is due to the max size of a valid length VarInt.<br />
|-<br />
! Chat<br />
| ≥ 1 <br />≤ (32767&times;4) + 3<br />
| See [[Chat]]<br />
| Encoded as a String with max length of 32767.<br />
|- <br />
! VarInt<br />
| ≥ 1 <br />≤ 5<br />
| An integer between -2147483648 and 2147483647<br />
| Variable-length data encoding a two's complement signed 32-bit integer; more info in [[#VarInt and VarLong|their section]]<br />
|-<br />
! VarLong<br />
| ≥ 1 <br />≤ 10<br />
| An integer between -9223372036854775808 and 9223372036854775807<br />
| Variable-length data encoding a two's complement signed 64-bit integer; more info in [[#VarInt and VarLong|their section]]<br />
|-<br />
! Chunk Section<br />
| Varies<br />
| A 16×16×16 chunk of blocks<br />
| See [[SMP Map Format]]<br />
|-<br />
! Entity Metadata<br />
| Varies<br />
| Miscellaneous information about an entity<br />
| See [[Entities#Entity Metadata Format]]<br />
|- <br />
! Slot<br />
| Varies<br />
| An item stack in an inventory or container<br />
| See [[Slot Data]]<br />
|-<br />
! NBT Tag<br />
| Varies<br />
| Depends on context<br />
| See [[NBT]]<br />
|-<br />
! Position <br />
| 8<br />
| An integer/block position: x (-33554432 to 33554431), y (-2048 to 2047), z (-33554432 to 33554431)<br />
| x as a 26-bit integer, followed by y as a 12-bit integer, followed by z as a 26-bit integer (all signed, two's complement). See also [[#Position|the section below]].<br />
|-<br />
! Angle<br />
| 1<br />
| A rotation angle in steps of 1/256 of a full turn<br />
| Whether or not this is signed does not matter, since the resulting angles are the same.<br />
|-<br />
! UUID<br />
| 16<br />
| A [[wikipedia:Universally_unique_identifier|UUID]]<br />
| Encoded as an unsigned 128-bit integer (or two unsigned 64-bit integers: the most significant 64 bits and then the least significant 64 bits)<br />
|-<br />
! Optional X<br />
| 0 or size of X<br />
| A field of type X, or nothing<br />
| Whether or not the field is present must be known from the context.<br />
|-<br />
! Array of X<br />
| count times size of X<br />
| Zero or more fields of type X<br />
| The count must be known from the context.<br />
|-<br />
! X Enum<br />
| size of X<br />
| A specific value from a given list<br />
| The list of possible values and how each is encoded as an X must be known from the context. An invalid value sent by either side will usually result in the client being disconnected with an error or even crashing.<br />
|-<br />
! Byte Array<br />
| Varies<br />
| Depends on context<br />
| This is just a sequence of zero or more bytes, its meaning should be explained somewhere else, e.g. in the packet description. The length must also be known from the context.<br />
|}<br />
<br />
<noinclude>== VarInt and VarLong ==</noinclude><includeonly>=== VarInt and VarLong ===</includeonly><br />
<br />
Variable-length format such that smaller numbers use fewer bytes. These are very similar to [http://developers.google.com/protocol-buffers/docs/encoding#varints Protocol Buffer Varints]: the 7 least significant bits are used to encode the value and the most significant bit indicates whether there's another byte after it for the next part of the number. The least significant group is written first, followed by each of the more significant groups; thus, VarInts are effectively little endian (however, groups are 7 bits, not 8).<br />
<br />
VarInts are never longer than 5 bytes, and VarLongs are never longer than 10 bytes.<br />
<br />
Pseudocode to read and write VarInts and VarLongs:<br />
<br />
<syntaxhighlight lang="java"><br />
public static int readVarInt() {<br />
int numRead = 0;<br />
int result = 0;<br />
byte read;<br />
do {<br />
read = readByte();<br />
int value = (read & 0b01111111);<br />
result |= (value << (7 * numRead));<br />
<br />
numRead++;<br />
if (numRead > 5) {<br />
throw new RuntimeException("VarInt is too big");<br />
}<br />
} while ((read & 0b10000000) != 0);<br />
<br />
return result;<br />
}<br />
</syntaxhighlight><br />
<syntaxhighlight lang="java"><br />
public static long readVarLong() {<br />
int numRead = 0;<br />
long result = 0;<br />
byte read;<br />
do {<br />
read = readByte();<br />
int value = (read & 0b01111111);<br />
result |= (value << (7 * numRead));<br />
<br />
numRead++;<br />
if (numRead > 10) {<br />
throw new RuntimeException("VarLong is too big");<br />
}<br />
} while ((read & 0b10000000) != 0);<br />
<br />
return result;<br />
}<br />
</syntaxhighlight><br />
<syntaxhighlight lang="java"><br />
public static void writeVarInt(int value) {<br />
do {<br />
byte temp = (byte)(value & 0b01111111);<br />
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone<br />
value >>>= 7;<br />
if (value != 0) {<br />
temp |= 0b10000000;<br />
}<br />
writeByte(temp);<br />
} while (value != 0);<br />
}<br />
</syntaxhighlight><br />
<syntaxhighlight lang="java"><br />
public static void writeVarLong(long value) {<br />
do {<br />
byte temp = (byte)(value & 0b01111111);<br />
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone<br />
value >>>= 7;<br />
if (value != 0) {<br />
temp |= 0b10000000;<br />
}<br />
writeByte(temp);<br />
} while (value != 0);<br />
}<br />
</syntaxhighlight><br />
<br />
{{Warning2|Note that Minecraft's VarInts are not encoded using Protocol Buffers; it's just similar. If you try to use Protocol Buffers Varints with Minecraft's VarInts, you'll get incorrect results in some cases. The major differences:<br />
*Minecraft's VarInts are all signed, but do not use the ZigZag encoding. Protocol buffers have 3 types of Varints: <code>uint32</code> (normal encoding, unsigned), <code>sint32</code> (ZigZag encoding, signed), and <code>int32</code> (normal encoding, signed). Minecraft's are the <code>int32</code> variety. Because Minecraft uses the normal encoding instead of ZigZag encoding, negative values always use the maximum number of bytes.<br />
*Minecraft's VarInts are never be longer than 5 bytes and its VarLongs will never be longer than 10 bytes, while Protocol Buffer Varints will always use 10 bytes when encoding negative numbers, even if it's an <code>int32</code>.}}<br />
<br />
Sample VarInts:<br />
<br />
{| class="wikitable"<br />
! Value !! Hex<br />
|-<br />
| 0 || 0x00<br />
|-<br />
| 1 || 0x01<br />
|-<br />
| 2 || 0x02<br />
|-<br />
| 127 || 0x7f<br />
|-<br />
| 128 || 0x80 0x01<br />
|-<br />
| 255 || 0xff 0x01<br />
|-<br />
| 2147483647 || 0xff 0xff 0xff 0xff 0x07<br />
|-<br />
| -1 || 0xff 0xff 0xff 0xff 0x0f<br />
|-<br />
| -2147483648 || 0x80 0x80 0x80 0x80 0x08 <br />
|}<br />
<br />
Sample VarLongs:<br />
<br />
{| class="wikitable"<br />
! Value !! Hex<br />
|-<br />
| 0 || 0x00<br />
|-<br />
| 1 || 0x01<br />
|-<br />
| 2 || 0x02<br />
|-<br />
| 127 || 0x7f<br />
|-<br />
| 128 || 0x80 0x01<br />
|-<br />
| 255 || 0xff 0x01<br />
|-<br />
| 2147483647 || 0xff 0xff 0xff 0xff 0x07<br />
|-<br />
| 9223372036854775807 || 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x7f<br />
|-<br />
| -1 || 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x01<br />
|-<br />
| -2147483648 || 0x80 0x80 0x80 0x80 0xf8 0xff 0xff 0xff 0xff 0x01<br />
|-<br />
| -9223372036854775808 || 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x01<br />
|}<br />
<br />
<noinclude>== Position ==</noinclude><includeonly>=== Position ===</includeonly><br />
<br />
64-bit value split in to three parts<br />
<br />
* x: 26 MSBs<br />
* z: 26 LSBs<br />
* y: 12 bits between them<br />
<br />
Encoded as followed:<br />
<br />
((x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF)<br />
<br />
And decoded as:<br />
<br />
val = read_unsigned_long();<br />
x = val >> 38;<br />
y = (val >> 26) & 0xFFF;<br />
z = val << 38 >> 38;<br />
<br />
Note: The details of bit shifting are rather language dependent; the above may work in Java but probably won't in other languages without some tweaking. In particular, you will usually receive positive numbers even if the actual coordinates are negative. This can be fixed by adding something like the following:<br />
<br />
if x >= 2^25 { x -= 2^26 }<br />
if y >= 2^11 { y -= 2^12 }<br />
if z >= 2^25 { z -= 2^26 }<br />
<br />
<noinclude>== Fixed-point numbers ==</noinclude><includeonly>=== Fixed-point numbers ===</includeonly><br />
<br />
Some fields may be stored as [https://en.wikipedia.org/wiki/Fixed-point_arithmetic fixed-point numbers], where a certain number of bits represents the signed integer part (number to the left of the decimal point) and the rest represents the fractional part (to the right). Floating points (float and double), in contrast, keep the number itself (mantissa) in one chunk, while the location of the decimal point (exponent) is stored beside it. <br />
<br />
Essentially, while fixed-point numbers have lower range than floating points, their fractional precision is greater for higher values. This makes them ideal for representing global coordinates of an entity in Minecraft, as it's more important to store the integer part accurately than position them more precisely within a single block (or meter). <br />
<br />
Coordinates are often represented as a 32-bit integer, where 5 of the least-significant bits are dedicated to the fractional part, and the rest store the integer part.<br />
<br />
Java lacks support for fractional integers directly, but you can represent them as integers. To convert from a double to this integer representation, use the following formulas:<br />
abs_int = (int)double * 32;<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<noinclude><br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Pre-release_protocol&diff=5977Pre-release protocol2014-08-06T18:02:40Z<p>Drainedsoul: Make it explicit that Packet Length includes Data Length</p>
<hr />
<div>This page documents the changes from the [[Protocol|last stable Minecraft release]] (currently 1.7.4, protocol 4) to the current pre-release. Note that this page contains bleeding-edge information that may not be completely or correctly documented.<br />
He who wishes to commandeer the merging of this into [[Protocol]] when an update is made must be sure to respect any changes that may have occured to the respective packets there.<br />
<br />
== Protocol History ==<br />
<br />
=== 14w32a ===<br />
<br />
* Added new Update Entity NBT packet<br />
* Added three new fields to Use Entity<br />
<br />
=== 14w31a ===<br />
<br />
* The length prefix on the payload of Plugin Message has been removed (Both ways)<br />
* Added new Resource Pack Send packet <br />
* Added new Resource Pack Status packet<br />
* Added VarLong data type<br />
* Changed a few fields in World Border to VarLong<br />
* Changed the type of Keep Alive ID from Int to VarInt (Clientbound)<br />
<br />
=== 14w30c ===<br />
<br />
=== 14w30a/b ===<br />
<br />
=== 14w29a ===<br />
<br />
* Fix the length prefix of Plugin Message so that its a Varint instead of an unsigned short<br />
* Added "Reduced Debug Info" boolean to Join Game<br />
* Added "Long Distance" boolean to Particle<br />
<br />
=== 14w28b ===<br />
<br />
* Uncompressed NBT<br />
* Added Display name fields to Player List Item<br />
* New 'Player List Header/Footer' packet<br />
<br />
=== 14w28a ===<br />
<br />
* Changed Chunk packets to remove compression<br />
* Added packets to toggle compression/set threshold<br />
* Allowed compression for the whole protocol<br />
* Changed the Maps packet<br />
<br />
=== 14w27a/b ===<br />
<br />
=== 14w26c ===<br />
<br />
* Changed Multi Block Change to using packed block ids<br />
* Changed Block Change to using packed block ids<br />
<br />
=== 14w26b ===<br />
<br />
* Bug fix<br />
<br />
=== 14w26a ===<br />
<br />
* Changed chunk sending<br />
<br />
=== 14w25b ===<br />
<br />
* Added boolean field to all entity movement packets<br />
<br />
=== 14w25a ===<br />
<br />
* Update Sign now uses [[Chat]]<br />
<br />
=== 14w21a ===<br />
<br />
* All byte arrays have VarInt length prefixes instead of short<br />
* Spawn Player changes<br />
* Player list item changes<br />
<br />
=== 14w20a ===<br />
<br />
* Added new packet 'Title'<br />
<br />
=== 14w19a ===<br />
<br />
* Changed the Particle's 'Particle Name' to an int<br />
* Added a new field to Particle<br />
* Rewrote Player List Item<br />
* Added SET_WARNING_TIME and SET_WARNING_BLOCKS to World Border<br />
* Added new serverbound packet Spectate<br />
<br />
=== 14w18b ===<br />
* Bugfix<br />
<br />
=== 14w18a ===<br />
* Added 'INITIALIZE' action to World Border<br />
<br />
=== 14w17a ===<br />
* Increased the max payload size of 'Plugin Message' from 32767 to 1048576 (Broken because of incorrect data type)<br />
* Added new packet 'World Border'<br />
<br />
=== 14w11a ===<br />
* UUIDs now include the '-'s<br />
<br />
=== 14w08a ===<br />
* Added new field 'Type' to Scoreboard Objective<br />
<br />
=== 14w07a ===<br />
* Added two new fields to Teams<br />
<br />
=== 14w06a ===<br />
<br />
==== Clientbound ====<br />
* Added new field 'Hide Particles' to Entity Effect<br />
<br />
==== Serverbound ====<br />
* Removed 'HeadY' from Player Position<br />
* Removed 'HeadY' from Player Position And Look<br />
<br />
=== 14w05a ===<br />
<br />
==== Clientbound ====<br />
* New packet 'Camera'<br />
<br />
=== 14w04b ===<br />
<br />
* Spawn Painting now uses the 'Position' data type<br />
* Changed Spawn Painting's Direction type to Unsigned Byte<br />
<br />
=== 14w04a ===<br />
<br />
* Encoding for 'Position' changed<br />
==== Clientbound ====<br />
* Changed Entity Equipment's EntityId type to VarInt<br />
* Changed Update Health's Food type to VarInt<br />
* Changed Use Bed's EntityId type to VarInt<br />
* Added new fields to Spawn Player<br />
* Changed Collect Item's EntityId(s) types to VarInt<br />
* Changed Entity Velocity's EntityId type to VarInt<br />
* Changed Destroy Entities' Length type to VarInt<br />
* Changed Destroy Entities' EntityIds type to VarInt array<br />
* Changed Entity's EntityId type to VarInt<br />
* Changed Entity Relative Move's EntityId type to VarInt<br />
* Changed Entity Look's EntityId type to VarInt<br />
* Changed Entity Look and Relative Move's EntityId type to VarInt<br />
* Changed Entity Teleport's EntityId type to VarInt<br />
* Changed Entity Head Look's EntityId type to VarInt<br />
* Changed Entity Metadata's EntityId type to Varint<br />
* Changed Entity Effect's EntityId type to VarInt<br />
* Changed Entity Effect's Duration type to VarInt<br />
* Changed Remove Entity Effect's EntityId type to VarInt<br />
* Changed Set Experience's Level type to VarInt<br />
* Changed Set Experience's Total Experience type to VarInt<br />
* Changed Entity Properties's EntityId type to VarInt<br />
* Changed Entity Properties's List Length type to VarInt<br />
* Changed Player List Item's Ping type to VarInt<br />
* Changed Update Score's Value type to VarInt<br />
* Changed Teams' Player count type to VarInt<br />
* New packet 'Combat Event'<br />
==== Serverbound ====<br />
* Changed Keep Alive's Keep Alive ID type to VarInt<br />
* Changed Use Entity's Target type to VarInt<br />
* Changed Use Entity's Mouse type to Unsigned Byte<br />
* Removed everything from Animation<br />
* Changed Entity Action's EntityId type to VarInt<br />
* Changed Entity Action's Action ID type to Unsigned Byte<br />
* Changed Entity Action's Values<br />
* Changed Entity Action's Jump Boast type to VarInt<br />
* Merged Steer Vehicle's Jump and Unmount into a Bit Field <br />
* Changed Client Status's Action ID type to Unsigned Byte<br />
<br />
=== 14w03a ===<br />
<br />
* New data type 'Position'<br />
==== Clientbound ====<br />
* Spawn Position now uses the 'Position' data type<br />
* Use Bed now uses the 'Position' data type<br />
* Block Change now uses the 'Position' data type<br />
* Block Action now uses the 'Position' data type<br />
* Block Break Animation now uses the 'Position' data type<br />
* Effect now uses the 'Position' data type<br />
* Sign Update now uses the 'Position' data type<br />
* Update Block Entity now uses the 'Position' data type<br />
* Sign Editor Open nows uses the 'Position' data type<br />
==== Serverbound ====<br />
* Player Digging now uses the 'Position' data type<br />
* Player Block Placement now uses the 'Position' data type<br />
* Update Sign now uses the 'Position' data type<br />
* Client Settings 'show cape' type changed from boolean to unsigned byte<br />
<br />
=== 14w02a ===<br />
<br />
* Added 'Position' to Chat Message Clientbound<br />
* Remove Player Position And Look's 'OnGround' clientbound<br />
* Added 'Flags' to Player Position And Look clientbound<br />
* Changed Open Inventory's 'Inventory Type' type from byte to string<br />
* Added Server Difficulty<br />
* Removed Client Settings' 'Difficulty'<br />
<br />
== Protocol Version ==<br />
<br />
{| class="wikitable"<br />
! Version !! Protocol<br />
|-<br />
| 14w02a || 5<br />
|-<br />
| 14w03a || 6<br />
|-<br />
| 14w04a || 7<br />
|-<br />
| 14w04b || 8<br />
|-<br />
| 14w05a || 9<br />
|-<br />
| 14w06a || 10<br />
|-<br />
| 14w07a || 11<br />
|-<br />
| 14w08a || 12<br />
|-<br />
| 14w11a || 14<br />
|-<br />
| 14w17a || 15<br />
|-<br />
| 14w18b || 16<br />
|-<br />
| 14w19a || 17<br />
|-<br />
| 14w20a || 18<br />
|-<br />
| 14w21a || 19<br />
|-<br />
| 14w21b || 20<br />
|-<br />
| 14w25a || 21<br />
|-<br />
| 14w25b || 22<br />
|-<br />
| 14w26a || 23<br />
|-<br />
| 14w26b || 24<br />
|-<br />
| 14w26c || 25<br />
|-<br />
| 14w27a/b || 26<br />
|-<br />
| 14w28a || 27<br />
|-<br />
| 14w28b || 28<br />
|-<br />
| 14w29a || 29<br />
|-<br />
| 14w30a || 30<br />
|-<br />
| 14w30c || 31<br />
|-<br />
| 14w31a || 32<br />
|-<br />
| 14w32a || 33<br />
|}<br />
<br />
== Packet format ==<br />
<br />
Once a Set Compression packet is sent, compression is enabled for all following packets. <br />
The format of a packet changes slighty to include the size of the uncompressed packet.<br />
<br />
{| class=wikitable<br />
! Name !! Type<br />
|-<br />
| Packet Length || VarInt<br />
|-<br />
| Data Length || VarInt<br />
|-<br />
| Data || <br />
|}<br />
<br />
If Data Length is set to zero, then the packet is uncompressed; otherwise it is the size of the uncompressed packet.<br />
<br />
If compressed, the data's length must be equal to or over the threshold set in the Set Compression packet, otherwise the client/server will disconnect.<br />
<br />
Compression can be disabled by sending a threshold of -1.<br />
<br />
The length given by the Packet Length field is the number of bytes that remain in that packet, including the Data Length field.<br />
<br />
== New data types ==<br />
<br />
=== Position ===<br />
<br />
Encoded as followed:<br />
<br />
(x & 0x3FFFFFF) << 38 | (y & 0xFFF) << 26 | (z & 0x3FFFFFF)<br />
<br />
<br />
And decoded as:<br />
<br />
long val; // Encoded value<br />
x = val >> 38;<br />
y = val << 26 >> 52<br />
z = val << 38 >> 38<br />
<br />
=== VarLong ===<br />
<br />
Like VarInt but based on java's long type instead of int<br />
<br />
== Play ==<br />
<br />
=== Clientbound ===<br />
<br />
==== Keep Alive ====<br />
<br />
The server will frequently send out a keep-alive, each containing a random ID. The client must respond with the same packet. If the client does not respond to them for over 30 seconds, the server kicks the client. Vice versa, if the server does not send any keep-alives for 20 seconds, the client will disconnect and yields a "Timed out" exception.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00 || rowspan=1 | Play || rowspan=1 | Client<br />
| Keep Alive ID || VarInt ||<br />
|}<br />
<br />
<br />
==== Join Game ====<br />
See [[Protocol Encryption]] for information on logging in.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7 | 0x01 || rowspan=7 | Play || rowspan=7 | Client<br />
| Entity ID || Int || The player's Entity ID<br />
|-<br />
| Gamemode || Unsigned Byte || 0: survival, 1: creative, 2: adventure. Bit 3 (0x8) is the hardcore flag<br />
|-<br />
| Dimension || Byte || -1: nether, 0: overworld, 1: end<br />
|-<br />
| Difficulty || Unsigned Byte || 0 thru 3 for Peaceful, Easy, Normal, Hard<br />
|-<br />
| Max Players || Unsigned Byte || Used by the client to draw the player list<br />
|-<br />
| Level Type || String || default, flat, largeBiomes, amplified, default_1_1<br />
|-<br />
| Reduced Debug Info || Boolean ||<br />
|}<br />
{{Warning|If the Dimension isn't valid then the client will crash}}<br />
<br />
==== Chat Message ==== <br />
<br />
Identifying the difference between Chat/System Message is important as it helps respect the user's chat visibility options. While position 2 accepts json formatting it will not display, old style formatting works<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x02<br />
| JSON Data || String || [[Chat]] , Limited to 32767 bytes<br />
|-<br />
| Position || Byte || 0 - Chat (chat box) ,1 - System Message (chat box), 2 - Above action bar<br />
|}<br />
{{Warning|Malformed JSON will disconnect the client}}<br />
<br />
==== Entity Equipment ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x04<br />
| EntityID || VarInt || Entity's ID<br />
|-<br />
| Slot || Short || Equipment slot: 0=held, 1-4=armor slot (1 - boots, 2 - leggings, 3 - chestplate, 4 - helmet)<br />
|-<br />
| Item || [[Slot_Data|Slot]] || Item in slot format<br />
|}<br />
<br />
==== Spawn Position ====<br />
<br />
Sent by the server after login to specify the coordinates of the spawn point (the point at which players spawn at, and which the compass points to). It can be sent at any time to update the point compasses point at.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x05<br />
| Location || Position || Spawn location<br />
|}<br />
<br />
==== Update Health ====<br />
<br />
Sent by the server to update/set the health of the player it is sent to.<br />
<br />
Food saturation acts as a food "overcharge". Food values will not decrease while the saturation is over zero. Players logging in automatically get a saturation of 5.0. Eating food increases the saturation as well as the food bar.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x06<br />
| Health || Float || 0 or less = dead, 20 = full HP<br />
|-<br />
| Food || VarInt || 0 - 20<br />
|- <br />
| Food Saturation || Float || Seems to vary from 0.0 to 5.0 in integer increments<br />
|}<br />
<br />
<br />
==== Player Position And Look ==== <br />
<br />
Updates the players position on the server. <br />
If the distance between the last known position of the player on the server and the new position set by this packet is greater than 100 units will result in the client being kicked for "You moved too quickly :( (Hacking?)"<br />
Also if the fixed-point number of X or Z is set greater than <code>3.2E7D</code> the client will be kicked for "Illegal position"<br />
<br />
Yaw is measured in degrees, and does not follow classical trigonometry rules. The unit circle of yaw on the XZ-plane starts at (0, 1) and turns counterclockwise, with 90 at (-1, 0), 180 at (0,-1) and 270 at (1, 0). Additionally, yaw is not clamped to between 0 and 360 degrees; any number is valid, including negative numbers and numbers greater than 360.<br />
<br />
Pitch is measured in degrees, where 0 is looking straight ahead, -90 is looking straight up, and 90 is looking straight down.<br />
<br />
The yaw of player (in degrees), standing at point (x0,z0) and looking towards point (x,z) one can be calculated with:<br />
l = x-x0<br />
w = z-z0<br />
c = sqrt( l*l + w*w )<br />
alpha1 = -arcsin(l/c)/PI*180<br />
alpha2 = arccos(w/c)/PI*180<br />
if alpha2 > 90 then<br />
yaw = 180 - alpha1<br />
else<br />
yaw = alpha1<br />
<br />
You can get a unit vector from a given yaw/pitch via:<br />
x = -cos(pitch) * sin(yaw)<br />
y = -sin(pitch)<br />
z = cos(pitch) * cos(yaw)<br />
<br />
About the flags field:<br />
<Dinnerbone> It's a bitfield, X/Y/Z/Y_ROT/X_ROT. If X is set, the x value is relative and not absolute.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6| 0x08<br />
| X || Double || Absolute/Relative position<br />
|-<br />
| Y || Double || Absolute/Relative position<br />
|-<br />
| Z || Double || Absolute/Relative position<br />
|-<br />
| Yaw || Float || Absolute/Relative rotation on the X Axis, in degrees<br />
|-<br />
| Pitch || Float || Absolute/Relative rotation on the Y Axis, in degrees<br />
|-<br />
| Flags || Byte || <br />
{| class="wikitable"<br />
| X || 0x01<br />
|-<br />
| Y || 0x02<br />
|-<br />
| Z || 0x04<br />
|-<br />
| Y_ROT || 0x08<br />
|-<br />
| X_ROT || 0x10<br />
|}<br />
|}<br />
<br />
==== Use Bed ==== <br />
<br />
This packet tells that a player goes to bed.<br />
<br />
The client with the matching Entity ID will go into bed mode.<br />
<br />
This Packet is sent to all nearby players including the one sent to bed.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x0A<br />
| Entity ID || VarInt || Player ID<br />
|-<br />
| Location || Position || Block location of the head part of the bed<br />
|}<br />
<br />
==== Spawn Player ====<br />
<br />
This packet is sent by the server when a player comes into visible range, '''not''' when a player joins.<br />
<br />
Servers can, however, safely spawn player entities for players not in visible range. The client appears to handle it correctly.<br />
<br />
When in online-mode the uuids must be valid and have valid skin blobs, in offline-mode uuid v3 is used.<br />
<br />
For NPCs UUID v2 should be used. Note:<br />
<+Grum> i will never confirm this as a feature you know that :)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! colspan=2 | Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=14 | 0x0C<br />
| colspan=2 | Entity ID || VarInt || Player's Entity ID<br />
|-<br />
| colspan=2 | Player UUID || UUID || Player's UUID<br />
|-<br />
| colspan=2 | X || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| colspan=2 | Y || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| colspan=2 | Z || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| colspan=2 | Yaw || Byte || Player rotation as a packed byte<br />
|-<br />
| colspan=2 | Pitch || Byte || Player rotation as a packet byte<br />
|-<br />
| colspan=2 | Current Item || Short || The item the player is currently holding. Note that this should be 0 for "no item", unlike -1 used in other packets. A negative value crashes clients.<br />
|-<br />
| colspan=2 | Metadata || [[Entities#Entity_Metadata_Format|Metadata]] || The client will crash if no metadata is sent<br />
|}<br />
{{Warning|The client will crash if no metadata is sent}}<br />
{{Warning|The client will disconnect if both UUID and Name are empty}}<br />
<br />
==== Collect Item ====<br />
<br />
Sent by the server when someone picks up an item lying on the ground - its sole purpose appears to be the animation of the item flying towards you. It doesn't destroy the entity in the client memory, and it doesn't add it to your inventory. The server only checks for items to be picked up after each Player Position and [Player Position & Look packet sent by the client.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x0D<br />
| Collected Entity ID || VarInt ||<br />
|- <br />
| Collector Entity ID || VarInt ||<br />
|}<br />
<br />
==== Spawn Painting ====<br />
<br />
This packet shows location, name, and type of painting.<br />
<br />
Calculating the center of an image: given a (width x height) grid of cells, with (0, 0) being the top left corner, the center is (max(0, width / 2 - 1), height / 2). E.g.<br />
<br />
2x1 (1, 0)<br />
4x4 (1, 2)<br />
<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x10<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Title || String || Name of the painting. Max length 13<br />
|-<br />
| Location || Position || Center coordinates<br />
|-<br />
| Direction || Unsigned Byte || Direction the painting faces (0 -z, 1 -x, 2 +z, 3 +x)<br />
|}<br />
<br />
<br />
==== Entity Velocity ====<br />
<br />
Velocity is believed to be in units of 1/8000 of a block per server tick (50ms);<br />
for example, -1343 would move (-1343 / 8000) = −0.167875 blocks per tick (or −3,3575 blocks per second).<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x12<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Velocity X || Short || Velocity on the X axis<br />
|-<br />
| Velocity Y || Short || Velocity on the Y axis<br />
|-<br />
| Velocity Z || Short || Velocity on the Z axis<br />
|}<br />
<br />
==== Destroy Entities ====<br />
<br />
Sent by the server when an list of Entities is to be destroyed on the client.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x13<br />
| Count || VarInt || Length of following array<br />
|-<br />
| Entity IDs || Array of VarInt || The list of entities of destroy <br />
|}<br />
<br />
==== Entity ====<br />
<br />
Most entity-related packets are subclasses of this packet. When sent from the server to the client, it may initialize the entry.<br />
<br />
For player entities, either this packet or any move/look packet is sent every game tick.<br />
So the meaning of this packet is basically that the entity did not move/look since the last such packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x14<br />
| Entity ID || VarInt || Entity's ID<br />
|}<br />
<br />
==== Entity Relative Move ====<br />
<br />
This packet is sent by the server when an entity moves less then 4 blocks; if an entity moves more than 4 blocks Entity Teleport should be sent instead.<br />
<br />
This packet allows at most four blocks movement in any direction, because byte range is from -128 to 127.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5| 0x15<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| DX || Byte || Change in X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DY || Byte || Change in Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DZ || Byte || Change in Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| On Ground || Boolean ||<br />
|}<br />
<br />
==== Entity Look ====<br />
<br />
This packet is sent by the server when an entity rotates. Example: "Yaw" field 64 means a 90 degree turn.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x16<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|-<br />
| On Ground || Boolean ||<br />
|}<br />
<br />
==== Entity Look and Relative Move ====<br />
<br />
This packet is sent by the server when an entity rotates and moves.<br />
Since a byte range is limited from -128 to 127, and movement is offset of fixed-point numbers,<br />
this packet allows at most four blocks movement in any direction. (-128/32 == -4)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7 | 0x17<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| DX || Byte || Change in X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DY || Byte || Change in Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DZ || Byte || Change in Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|-<br />
| On Ground || Boolean ||<br />
|}<br />
<br />
==== Entity Teleport ====<br />
<br />
This packet is sent by the server when an entity moves more than 4 blocks.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=8 | 0x18<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| X || Int || X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Y || Int || Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Z || Int || Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|-<br />
| On Ground || Boolean ||<br />
|}<br />
<br />
==== Entity Head Look ====<br />
<br />
Changes the direction an entity's head is facing.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x19<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Head Yaw || Byte || Head yaw in steps of 2p/256<br />
|}<br />
<br />
==== Entity Metadata ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x1C<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Metadata || [[Entities#Entity_Metadata_Format|Metadata]] || <br />
|}<br />
<br />
<br />
==== Entity Effect ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x1D<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Effect ID || Byte || See [[http://www.minecraftwiki.net/wiki/Potion_effect#Parameters]]<br />
|-<br />
| Amplifier || Byte || <br />
|-<br />
| Duration || VarInt ||<br />
|-<br />
| Hide Particles || Boolean ||<br />
|}<br />
<br />
==== Remove Entity Effect ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x1E<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Effect ID || Byte ||<br />
|}<br />
<br />
==== Set Experience ====<br />
<br />
Sent by the server when the client should change experience levels.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x1F<br />
| Experience bar || Float || Between 0 and 1<br />
|-<br />
| Level || VarInt ||<br />
|-<br />
| Total Experience || VarInt ||<br />
|}<br />
<br />
==== Entity Properties ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x20<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Count || Int || Length of following array<br />
|-<br />
| Properties || Array of Property Data ||<br />
|}<br />
<br />
'''Property Data''' structure:<br />
{| class="wikitable"<br />
|-<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| Key || String || <br />
|-<br />
| Value || Double || <br />
|-<br />
| List Length || VarInt || Number of list elements that follow.<br />
|-<br />
| Modifiers || Array of Modifier Data || http://www.minecraftwiki.net/wiki/Attribute#Modifiers<br />
|}<br />
<br />
Known key values:<br />
{| class="wikitable"<br />
|-<br />
! Key !! Default !! Min !! Max !! Label<br />
|-<br />
| generic.maxHealth || 20.0 || 0.0 || Double.MaxValue || Max Health<br />
|-<br />
| generic.followRange || 32.0 || 0.0 || 2048.0 || Follow Range<br />
|-<br />
| generic.knockbackResistance || 0.0 || 0.0 || 1.0 || Knockback Resistance<br />
|-<br />
| generic.movementSpeed || 0.699999988079071 || 0.0 || Double.MaxValue || Movement Speed<br />
|-<br />
| generic.attackDamage || 2.0 || 0.0 || Double.MaxValue || <br />
|-<br />
| horse.jumpStrength || 0.7 || 0.0 || 2.0 || Jump Strength<br />
|-<br />
| zombie.spawnReinforcements || 0.0 || 0.0 || 1.0 || Spawn Reinforcements Chance<br />
|}<br />
<br />
'''Modifier Data''' structure:<br />
{| class="wikitable"<br />
|-<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| UUID || 128-bit integer ||<br />
|-<br />
| Amount || Double ||<br />
|-<br />
| Operation || Byte ||<br />
|}<br />
<br />
==== Chunk Data ====<br />
<br />
Chunks are not unloaded by the client automatically. To unload chunks, send this packet with ground-up continuous=true and no 16^3 chunks (eg. primary bit mask=0). The server does not send skylight information for nether-chunks, it's up to the client to know if the player is currently in the nether. You can also infer this information from the primary bitmask and the amount of uncompressed bytes sent.<br />
<br />
See also: [[SMP Map Format]]<br />
<br />
Changes in 14w26a:<br />
<br />
* Data value section removed<br />
* Extended id section removed<br />
* Block id section is now a unsigned short per a block<br />
* The block id is equal to <code>(id << 4) | data</code><br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7 | 0x21 || rowspan=7 | Play || rowspan=7 | Client<br />
| Chunk X || Int || Chunk X coordinate<br />
|-<br />
| Chunk Z || Int || Chunk Z coordinate<br />
|-<br />
| Ground-Up continuous || Boolean || This is True if the packet represents all sections in this vertical column, where the primary bit map specifies exactly which sections are included, and which are air<br />
|-<br />
| Primary bit map || Unsigned Short || Bitmask with 1 for every 16x16x16 section which data follows in the compressed data.<br />
|- <br />
| Size || VarInt || Size of chunk data<br />
|-<br />
| Data || Byte array || The chunk data is not compressed as of 14w28a<br />
|}<br />
<br />
<br />
==== Multi Block Change ====<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x22 || rowspan=4 | Play || rowspan=4 | Client<br />
| Chunk X || Int || Chunk X coordinate<br />
|-<br />
| Chunk Z || Int || Chunk Z Coordinate<br />
|-<br />
| Record count || VarInt || The number of blocks affected<br />
|-<br />
| Records || Array of Records || <br />
|}<br />
<br />
'''Record'''<br />
{| class="wikitable"<br />
|-<br />
! Bit mask !! Width !! Meaning<br />
|-<br />
| 00 00 00 0F || 4 bits || Block metadata<br />
|-<br />
| 00 00 FF F0 || 12 bits || Block ID<br />
|-<br />
| 00 FF 00 00 || 8 bits || Y co-ordinate<br />
|-<br />
| 0F 00 00 00 || 4 bits || Z co-ordinate, relative to chunk<br />
|-<br />
| F0 00 00 00 || 4 bits || X co-ordinate, relative to chunk<br />
|}<br />
<br />
<br />
==== Block Change ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x23<br />
| Location || Position|| Block Coordinates<br />
|-<br />
| Block ID || VarInt || The new block ID for the block. <code>id << 4 | data</code><br />
|}<br />
<br />
==== Block Action ====<br />
<br />
This packet is used for a number of things:<br />
* <div class="li">Chests opening and closing<br />
* Pistons pushing and pulling<br />
* Note blocks playing<br />
<br />
See Also: [[Block Actions]] <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x24<br />
| Location || Position || Block Coordinates<br />
|-<br />
| Byte 1 || Unsigned Byte || Varies depending on block - see [[Block_Actions]]<br />
|-<br />
| Byte 2 || Unsigned Byte || Varies depending on block - see [[Block_Actions]]<br />
|-<br />
| Block Type || VarInt || The block type for the block<br />
|}<br />
<br />
==== Block Break Animation ====<br />
<br />
0-9 are the displayable destroy stages and each other number means that there is no animation on this coordinate.<br />
<br />
You can also set an animation to air! The animation will still be visible.<br />
<br />
If you need to display several break animations at the same time you have to give each of them a unique Entity ID.<br />
<br />
Also if you set the coordinates to a special block like water etc. it won't show the actual break animation but some other interesting effects. (Water will loose it's transparency)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x25<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Location || Position || Block Position<br />
|-<br />
| Destroy Stage || Byte || 0 - 9<br />
|}<br />
<br />
==== Map Chunk Bulk ====<br />
<br />
See also: [[SMP Map Format]]<br />
<br />
Snapshot changes at [[#Chunk_Data]]<br />
<br />
To reduce the number of bytes this packet is used to send chunks together for better compression results.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x26 || rowspan=5 | Play || rowspan=5 | Client<br />
| Sky light sent || Bool || Whether or not the chunk data contains a light nibble array. This is true in the main world, false in the end + nether<br />
|-<br />
| Chunk column count || VarInt || The number of chunk in this packet<br />
|-<br />
| Meta information || Meta || See below <br />
|-<br />
| Data || Byte Array || Chunk data. Uncompressed as of 14w28a<br />
|}<br />
<br />
'''Meta'''<br />
{| class="wikitable"<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
|Chunk X || Int || The X Coordinate of the chunk<br />
|-<br />
|Chunk Z || Int || The Z Coordinate of the chunk<br />
|-<br />
|Primary bitmap || Unsigned Short || A bitmap which specifies which sections are not empty in this chunk<br />
|}<br />
<br />
==== Effect ====<br />
<br />
Sent when a client is to play a sound or particle effect.<br />
<br />
By default, the minecraft client adjusts the volume of sound effects based on distance. The final boolean field is used to disable this, and instead the effect is played from 2 blocks away in the correct direction. Currently this is only used for effect 1013 (mob.wither.spawn), and is ignored for any other value by the client.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x28<br />
| Effect ID || Int || The ID of the effect, see below.<br />
|-<br />
| Location || Position|| The location of the effect<br />
|-<br />
| Data || Int || Extra data for certain effects, see below.<br />
|-<br />
| Disable relative volume || Bool || See above<br />
|}<br />
<br />
===== Effects =====<br />
<br />
{| class="wikitable"<br />
! ID !! Name<br />
|-<br />
| colspan=2 | '''Sound'''<br />
|-<br />
| 1000|| <code>random.click</code><br />
|-<br />
| 1001|| <code>random.click</code><br />
|-<br />
| 1002|| <code>random.bow</code><br />
|-<br />
| 1003|| <code>random.door_open</code> or <code>random.door_close</code> (50/50 chance)<br />
|-<br />
| 1004|| <code>random.fizz</code><br />
|-<br />
| 1005|| Play a music disc. '''Data''' [http://www.minecraftwiki.net/wiki/Music_Discs Record ID]<br />
|-<br />
| ''(1006 not assigned)'' ||<br />
|-<br />
| 1007|| <code>mob.ghast.charge</code><br />
|-<br />
| 1008|| <code>mob.ghast.fireball</code><br />
|-<br />
| 1009|| <code>mob.ghast.fireball</code>, but with a lower volume.<br />
|-<br />
| 1010|| <code>mob.zombie.wood</code><br />
|-<br />
| 1011|| <code>mob.zombie.metal</code><br />
|-<br />
| 1012|| <code>mob.zombie.woodbreak</code><br />
|-<br />
| 1013|| <code>mob.wither.spawn</code><br />
|-<br />
| 1014|| <code>mob.wither.shoot</code><br />
|-<br />
| 1015|| <code>mob.bat.takeoff</code><br />
|-<br />
| 1016|| <code>mob.zombie.infect</code><br />
|-<br />
| 1017|| <code>mob.zombie.unfect</code><br />
|-<br />
| 1018|| <code>mob.enderdragon.end</code><br />
|-<br />
| 1020|| <code>random.anvil_break</code><br />
|-<br />
| 1021|| <code>random.anvil_use</code><br />
|-<br />
| 1022|| <code>random.anvil_land</code><br />
|-<br />
| colspan=2 | '''Particle'''<br />
|-<br />
| 2000|| Spawns 10 smoke particles, e.g. from a fire. '''Data''' direction, see below<br />
|-<br />
| 2001|| Block break. '''Data''' [http://www.minecraftwiki.net/wiki/Data_values Block ID]<br />
|-<br />
| 2002|| Splash potion. Particle effect + glass break sound. '''Data''' [http://www.lb-stuff.com/Minecraft/PotionDataValues1.9pre3.txt Potion ID]<br />
|-<br />
| 2003|| Eye of ender entity break animation - particles and sound<br />
|-<br />
| 2004|| Mob spawn particle effect: smoke + flames<br />
|-<br />
| 2005|| Spawn "happy villager" effect (green crosses), used for bonemealing vegetation.<br />
|}<br />
<br />
Smoke directions:<br />
<br />
{| class="wikitable"<br />
! ID !! Direction<br />
|-<br />
| 0 || South - East<br />
|-<br />
| 1 || South<br />
|-<br />
| 2 || South - West<br />
|-<br />
| 3 || East<br />
|-<br />
| 4 || (Up or middle ?)<br />
|-<br />
| 5 || West<br />
|-<br />
| 6 || North - East<br />
|-<br />
| 7 || North<br />
|-<br />
| 8 || North - West<br />
|}<br />
<br />
==== Particle ====<br />
<br />
Displays the named particle<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="11" | 0x2A<br />
| Particle Id || Int || <br />
|-<br />
| Long Distance || Boolean || If true, particle distance increases from 256 to 65536.<br />
|-<br />
| X || Float || X position of the particle<br />
|-<br />
| Y || Float || Y position of the particle<br />
|-<br />
| Z || Float || Z position of the particle<br />
|-<br />
| Offset X || Float || This is added to the X position after being multiplied by random.nextGaussian() <br />
|-<br />
| Offset Y || Float || This is added to the Y position after being multiplied by random.nextGaussian() <br />
|-<br />
| Offset Z || Float || This is added to the Z position after being multiplied by random.nextGaussian() <br />
|-<br />
| Particle data || Float || The data of each particle<br />
|-<br />
| Number of particles || Int || The number of particles to create<br />
|-<br />
| Data || Array of VarInt || Length depends on particle. ICON_CRACK, BLOCK_CRACK, and BLOCK_DUST have lengths of 2, the rest have 0.<br />
|}<br />
<br />
==== Open Window ====<br />
<br />
This is sent to the client when it should open an inventory, such as a chest, workbench, or furnace. This message is not sent anywhere for clients opening their own inventory.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x2D<br />
| Window id || Unsigned Byte || A unique id number for the window to be displayed. Notchian server implementation is a counter, starting at 1.<br />
|-<br />
| Inventory Type || String || The window type to use for display. Check below<br />
|-<br />
| Window title || String (JSON) || The title of the window.<br />
|-<br />
| Number of Slots || Unsigned Byte || Number of slots in the window (excluding the number of slots in the player inventory).<br />
|-<br />
| Entity ID || Int || EntityHorse's entityId. Only sent when window type is equal to "EntityHorse".<br />
|}<br />
<br />
See [[Inventory#Windows|inventory windows]] for further information.<br />
<br />
==== Update Sign ====<br />
<br />
This message is sent from the server to the client whenever a sign is discovered or created. This message is NOT sent when a sign is destroyed or unloaded.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="7" | 0x33<br />
| Location || Position || Block Coordinates<br />
|-<br />
| Line 1 || [[Chat]] || First line of text in the sign<br />
|-<br />
| Line 2 || [[Chat]] || Second line of text in the sign<br />
|-<br />
| Line 3 || [[Chat]] || Third line of text in the sign<br />
|-<br />
| Line 4 || [[Chat]] || Fourth line of text in the sign<br />
|}<br />
<br />
==== Maps ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="10" | 0x34 || rowspan=10 | Play || rowspan=10 | Client<br />
| Item Damage || VarInt || The damage value of the map being modified<br />
|-<br />
| Scale || Byte || <br />
|- <br />
| Length || VarInt ||<br />
|-<br />
| Icons || 3 * length bytes || First byte, 0xF0 = Direction, 0x0F = Type. Second byte, X. Third byte, Y<br />
|- <br />
| Columns || Byte ||<br />
|-<br />
| Rows || Byte || Only if Columns is more than 0<br />
|-<br />
| X || Byte || Only if Columns is more than 0<br />
|-<br />
| Y || Byte || Only if Columns is more than 0<br />
|-<br />
| Length || VarInt || Only if Columns is more than 0<br />
|-<br />
| Data || Length bytes || Only if Columns is more than 0<br />
|}<br />
<br />
==== Update Block Entity ====<br />
<br />
Essentially a block update on a block entity.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x35<br />
| Location || Position ||<br />
|-<br />
| Action || Unsigned Byte || The type of update to perform<br />
|-<br />
| Data length || Short || Varies<br />
|-<br />
| NBT Data || Byte Array || Present if data length > 0. Varies<br />
|}<br />
<br />
'''Actions'''<br />
<br />
* '''1''': Set mob displayed inside a mob spawner. Custom 1 contains the [[Entities#Mobs|mob type]]<br />
<br />
==== Sign Editor Open ====<br />
<br />
Sent on placement of sign.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x36<br />
| Location || Position || Block coordinates<br />
|}<br />
<br />
==== Player List Item ====<br />
<br />
Sent by the notchian server to update the user list (<tab> in the client).<br />
<br />
{| class="wikitable"<br />
! Packet ID !! colspan="3" | Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="19" | 0x38<br />
| colspan="3" | Action || VarInt || <br />
|-<br />
| colspan="3" | Length || VarInt || The following fields are repeated ''length'' times<br />
|-<br />
| colspan="3" | UUID || UUID || The uuid of the player<br />
|-<br />
! Action !! colspan=4 | <br />
|-<br />
| rowspan="10" | 0 (ADD_PLAYER) <br />
| colspan="2" | Name || String ||<br />
|-<br />
| colspan="2" | Number of properties || VarInt || <br />
|-<br />
| rowspan="4" | Properties <br />
| Name || String ||<br />
|-<br />
| Value || String ||<br />
|- <br />
| Is Signed || Boolean ||<br />
|-<br />
| Signature || String || Only if Is Signed is true<br />
|-<br />
| colspan="2" | Gamemode || VarInt ||<br />
|-<br />
| colspan="2" | Ping || VarInt ||<br />
|-<br />
| colspan="2" | Has Display Name || Boolean ||<br />
|-<br />
| colspan="2" | Display Name || [[Chat]] || Only send if Has Diplay Name is true<br />
|-<br />
| 1 (UPDATE_GAMEMODE) || colspan="2" | Gamemode || VarInt ||<br />
|- <br />
| 2 (UPDATE_LATENCY) || colspan="2" | Ping || VarInt ||<br />
|-<br />
| rowspan="2" | 3 (UPDATE_DISPLAY_NAME) <br />
| colspan="2" | Has Display Name || Boolean ||<br />
|-<br />
| colspan="2" | Display Name || [[Chat]] || Only send if Has Diplay Name is true<br />
|-<br />
| 4 (REMOVE_PLAYER) || colspan="2" | || ||<br />
|}<br />
<br />
==== Scoreboard Objective ====<br />
<br />
This is sent to the client when it should create a new scoreboard or remove one.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x3B<br />
| Objective name || String || An unique name for the objective<br />
|-<br />
| Mode || Byte || 0 to create the scoreboard. 1 to remove the scoreboard. 2 to update the display text. <br />
|-<br />
| Objective value || String || Only if mode is 0 or 2. The text to be displayed for the score.<br />
|-<br />
| Type || String || Only if mode is 0 or 2. "integer" or "hearts" <br />
|}<br />
<br />
==== Update Score ====<br />
<br />
This is sent to the client when it should update a scoreboard item. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x3C<br />
| Item Name || String || An unique name to be displayed in the list.<br />
|-<br />
| Update/Remove || Byte || 0 to create/update an item. 1 to remove an item.<br />
|-<br />
| Score Name || String || The unique name for the scoreboard to be updated. Only sent when Update/Remove does not equal 1.<br />
|-<br />
| Value || VarInt || The score to be displayed next to the entry. Only sent when Update/Remove does not equal 1.<br />
|}<br />
{{Warning|The final String and Int are only sent if the Update/Remove Byte does not equal 1}}<br />
<br />
==== Teams ====<br />
<br />
Creates and updates teams.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="10" | 0x3E<br />
| Team Name || String || A unique name for the team. (Shared with scoreboard).<br />
|-<br />
| Mode || Byte || If 0 then the team is created. <br />
If 1 then the team is removed. <br />
<br />
If 2 the team team information is updated. <br />
<br />
If 3 then new players are added to the team. <br />
<br />
If 4 then players are removed from the team.<br />
|-<br />
| Team Display Name || String || Only if Mode = 0 or 2. <br />
|-<br />
| Team Prefix || String || Only if Mode = 0 or 2. Displayed before the players' name that are part of this team. <br />
|-<br />
| Team Suffix || String || Only if Mode = 0 or 2. Displayed after the players' name that are part of this team. <br />
|-<br />
| Friendly fire || Byte || Only if Mode = 0 or 2; 0 for off, 1 for on, 3 for seeing friendly invisibles<br />
|-<br />
| Name Tag Visibility || String || Only if Mode = 0 or 2. always, hideForOtherTeams, hideForOwnTeam, never. <br />
|-<br />
| Color || Byte || Only if Mode = 0 or 2. Same as [[Chat]] colors.<br />
|-<br />
| Player count || VarInt || Only if Mode = 0 or 3 or 4. Number of players in the array<br />
|-<br />
| Players || Array of strings || Only if Mode = 0 or 3 or 4. Players to be added/remove from the team. Max 40 characters so may be uuid's later<br />
|}<br />
<br />
==== Plugin Message ====<br />
<br />
Mods and plugins can use this to send their data. Minecraft itself uses a number of [[plugin channel]]s. These internal channels are prefixed with <code>MC|</code>.<br />
<br />
More documentation on this: http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x3F || rowspan=3 | Play || rowspan=3 | Client<br />
| Channel || String || Name of the "channel" used to send the data.<br />
|-<br />
| Data || Byte Array || Any data.<br />
|}<br />
<br />
<br />
==== Server Difficulty ====<br />
<br />
Changes the difficulty setting in the client's option menu<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="1" | 0x41<br />
| Difficulty || Unsigned Byte || 0:PEACEFUL, 1:EASY, 2:NORMAL, 3: HARD<br />
|}<br />
<br />
<br />
==== Combat Event ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x42<br />
| Event || Unsigned Byte || 0 ENTER_COMBAT, 1 END_COMBAT, 2 ENTITY_DEAD<br />
|-<br />
| Duration || VarInt || Only for END_COMBAT<br />
|-<br />
| Entity ID || Int || Only for END_COMBAT<br />
|-<br />
| Player ID || VarInt || Only for ENTITY_DEAD<br />
|-<br />
| Entity ID || Int || Only for ENTITY_DEAD<br />
|-<br />
| Message || String || Only for ENTITY_DEAD<br />
|}<br />
<br />
==== Camera ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x43<br />
| Camera ID || VarInt ||<br />
|}<br />
<br />
==== World Border ==== <br />
<br />
{| class="wikitable"<br />
! Packet ID !! colspan=2 | Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=18 | 0x44<br />
| colspan=2 | Action || VarInt ||<br />
|-<br />
! Action !! Name !! !!<br />
|-<br />
| 0 (SET_SIZE)<br />
| Radius || Double ||<br />
|-<br />
| rowspan=3 | 1 (LERP_SIZE)<br />
| Old radius || Double ||<br />
|-<br />
| New radius || Double ||<br />
|-<br />
| Speed || VarLong ||<br />
|-<br />
| rowspan=2 | 2 (SET_CENTER)<br />
| X || Double || <br />
|-<br />
| Z || Double ||<br />
|-<br />
| rowspan=8 | 3 (INITIALIZE)<br />
| X || Double ||<br />
|-<br />
| Z || Double ||<br />
|-<br />
| Old radius || Double ||<br />
|-<br />
| New radius || Double ||<br />
|-<br />
| Speed || VarLong ||<br />
|-<br />
| Portal Teleport Boundary || VarInt || Resulting coordinates from a portal teleport are limited to +-value. Usually 29999984.<br />
|-<br />
| Warning time || VarInt ||<br />
|-<br />
| Warning blocks || VarInt ||<br />
|-<br />
| rowspan=1 | 4 (SET_WARNING_TIME)<br />
| Warning time || VarInt ||<br />
|-<br />
| rowspan=1 | 5 (SET_WARNING_BLOCKS)<br />
| Warning blocks || VarInt ||<br />
|}<br />
<br />
==== Title ==== <br />
<br />
{| class="wikitable"<br />
! Packet ID !! colspan=2 | Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=9 | 0x45<br />
| colspan=2 | Action || VarInt ||<br />
|-<br />
! Action !! Name !! !!<br />
|-<br />
| 0 (TITLE) || Text || JSON Chat String ||<br />
|-<br />
| 1 (SUBTITLE) || Text || JSON Chat String ||<br />
|-<br />
| rowspan=3 | 2 (TIMES) <br />
| Fade In || Int || <br />
|-<br />
| Stay || Int || <br />
|-<br />
| Fade Out || Int ||<br />
|-<br />
| 3 (CLEAR) || || ||<br />
|-<br />
| 4 (RESET) || || ||<br />
|}<br />
<br />
==== Set Compression ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x46<br />
| Threshold || VarInt || Threshold is the max size of a packet before its compressed<br />
|}<br />
<br />
==== Player List Header/Footer ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x47<br />
| Header || [[Chat]] || <br />
|-<br />
| Footer || [[Chat]] || <br />
|}<br />
<br />
==== Resource Pack Send ==== <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x48<br />
| URL || String || <br />
|-<br />
| Hash || String || If it's not a 40 character hexadecimal string, the client will not use it for hash verification and likely waste bandwidth - but it will still treat it as a unique id <br />
|}<br />
<br />
==== Update Entity NBT ==== <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x49<br />
| Entity ID || VarInt || <br />
|-<br />
| Tag || NBT Tag ||<br />
|}<br />
<br />
=== Serverbound ===<br />
<br />
==== Keep Alive ====<br />
<br />
The server will frequently send out a keep-alive, each containing a random ID. The client must respond with the same packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00<br />
| Keep Alive ID || VarInt ||<br />
|}<br />
<br />
==== Use Entity ====<br />
<br />
This packet is sent from the client to the server when the client attacks or right-clicks another entity (a player, minecart, etc).<br />
<br />
A Notchian server only accepts this packet if the entity being attacked/used is visible without obstruction and within a 4-unit radius of the player's position.<br />
<br />
Note that middle-click in creative mode is interpreted by the client and sent as a Creative Inventory Action packet instead.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x02<br />
| Target || VarInt ||<br />
|-<br />
| Type || VarInt || 0 = INTERACT, 1 = ATTACK, 2 = INTERACT_AT<br />
|-<br />
| Target X || Float || Only if Type == INTERACT_AT<br />
|-<br />
| Target Y || Float || Only if Type == INTERACT_AT<br />
|-<br />
| Target Z || Float || Only if Type == INTERACT_AT<br />
|}<br />
<br />
==== Player Position ====<br />
<br />
Updates the players XYZ position on the server. <br />
If <code>HeadY - FeetY</code> is less than <code>0.1</code> or greater than <code>1.65</code>, the stance is illegal and the client will be kicked with the message “Illegal Stance”.<br />
If the distance between the last known position of the player on the server and the new position set by this packet is greater than 100 units will result in the client being kicked for "You moved too quickly :( (Hacking?)"<br />
Also if the fixed-point number of X or Z is set greater than <code>3.2E7D</code> the client will be kicked for "Illegal position" <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5| 0x04<br />
| X || Double || Absolute position<br />
|-<br />
| FeetY || Double || Absolute feet position, normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc…<br />
|-<br />
| Z || Double || Absolute position<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Player Position And Look ====<br />
<br />
A combination of Player Look and Player position. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7| 0x06<br />
| X || Double || Absolute position<br />
|-<br />
| FeetY || Double || Absolute feet position. Is normally HeadY - 1.62. Used to modify the players bounding box when going up stairs, crouching, etc…<br />
|-<br />
| Z || Double || Absolute position<br />
|-<br />
| Yaw || Float || Absolute rotation on the X Axis, in degrees<br />
|-<br />
| Pitch || Float || Absolute rotation on the Y Axis, in degrees<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
<br />
==== Player Digging ====<br />
<br />
Sent when the player mines a block. A Notchian server only accepts digging packets with coordinates within a 6-unit radius of the player's position.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x07<br />
| Status || Byte || The action the player is taking against the block (see below)<br />
|-<br />
| Location || Position || Block position<br />
|-<br />
| Face || Byte || The face being hit (see below)<br />
|}<br />
<br />
Status can (currently) be one of six values:<br />
<br />
{| class="wikitable"<br />
! Meaning !! Value<br />
|-<br />
| Started digging || <code>0</code><br />
|-<br />
| Cancelled digging || <code>1</code><br />
|-<br />
| Finished digging || <code>2</code><br />
|-<br />
| Drop item stack || <code>3</code><br />
|-<br />
| Drop item || <code>4</code><br />
|-<br />
| Shoot arrow / finish eating || <code>5</code><br />
|}<br />
<br />
Notchian clients send a 0 (started digging) when they start digging and a 2 (finished digging) once they think they are finished. If digging is aborted, the client simply send a 1 (Cancel digging).<br />
<br />
Status code 4 (drop item) is a special case. In-game, when you use the Drop Item command (keypress 'q'), a dig packet with a status of 4, and all other values set to 0, is sent from client to server. Status code 3 is similar, but drops the entire stack.<br />
<br />
Status code 5 (shoot arrow / finish eating) is also a special case. The x, y and z fields are all set to 0 like above, with the exception of the face field, which is set to 255.<br />
<br />
The face can be one of six values, representing the face being hit:<br />
<br />
{| class="wikitable"<br />
|-<br />
| Value || 0 || 1 || 2 || 3 || 4 || 5<br />
|-<br />
| Offset || -Y || +Y || -Z || +Z || -X || +X<br />
|}<br />
<br />
In 1.7.3, when a player opens a door with left click the server receives Packet 0xE+start digging and opens the door.<br />
<br />
==== Player Block Placement ====<br />
{| class="wikitable"<br />
|-<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x08<br />
| Location || Position || Block position<br />
|-<br />
| Direction || Byte || The offset to use for block/item placement (see below)<br />
|-<br />
| Held item || [[Slot_Data|Slot]] ||<br />
|-<br />
| Cursor position X || Byte || The position of the crosshair on the block<br />
|-<br />
| Cursor position Y || Byte ||<br />
|-<br />
| Cursor position Z || Byte ||<br />
|}<br />
In normal operation (ie placing a block), this packet is sent once, with the values set normally.<br />
<br />
This packet has a special case where X, Y, Z, and Direction are all -1. (Note that Y is unsigned so set to 255.) This special packet indicates that the currently held item for the player should have its state updated such as eating food, shooting bows, using buckets, etc.<br />
<br />
In a Notchian Beta client, the block or item ID corresponds to whatever the client is currently holding, and the client sends one of these packets any time a right-click is issued on a surface, so no assumptions can be made about the safety of the ID. However, with the implementation of server-side inventory, a Notchian server seems to ignore the item ID, instead operating on server-side inventory information and holding selection. The client has been observed (1.2.5 and 1.3.2) to send both real item IDs and -1 in a single session.<br />
<br />
Special note on using buckets: When using buckets, the Notchian client might send two packets: first a normal and then a special case. The first normal packet is sent when you're looking at a block (e.g. the water you want to scoop up). This normal packet does not appear to do anything with a Notchian server. The second, special case packet appears to perform the action - based on current position/orientation and with a distance check - it appears that buckets can only be used within a radius of 6 units.<br />
<br />
==== Animation ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x0A || || ||<br />
|}<br />
<br />
==== Entity Action ====<br />
<br />
Sent at least when crouching, leaving a bed, or sprinting.<br />
To send action animation to client use 0x28.<br />
The client will send this with Action ID = 3 when "Leave Bed" is clicked.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x0B<br />
| Entity ID || VarInt || Player ID<br />
|-<br />
| Action ID || Unsigned Byte || The ID of the action, see below.<br />
|-<br />
| Jump Boost || VarInt || Horse jump boost. Ranged from 0 -> 100.<br />
|}<br />
<br />
Action ID can be one of the following values:<br />
<br />
{| class="wikitable"<br />
! ID !! Action<br />
|-<br />
| 0 || Crouch<br />
|-<br />
| 1 || Uncrouch<br />
|-<br />
| 2 || Leave bed<br />
|-<br />
| 3 || Start sprinting<br />
|-<br />
| 4 || Stop sprinting<br />
|-<br />
| 5 || Jump with horse<br />
|-<br />
| 6 || Open inventory<br />
|}<br />
<br />
==== Steer Vehicle ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x0C<br />
| Sideways || Float || Positive to the left of the player<br />
|-<br />
| Forward || Float || Positive forward<br />
|-<br />
| Flags|| Unsigned Byte || 0x1 Jump, 0x2 Unmount<br />
|}<br />
<br />
<br />
<br />
==== Update Sign ====<br />
<br />
This message is sent from the client to the server when the "Done" button is pushed after placing a sign. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="7" | 0x12<br />
| Location || Position || Block Coordinates<br />
|-<br />
| Line 1 || [[Chat]] || First line of text in the sign<br />
|-<br />
| Line 2 || [[Chat]] || Second line of text in the sign<br />
|-<br />
| Line 3 || [[Chat]] || Third line of text in the sign<br />
|-<br />
| Line 4 || [[Chat]] || Fourth line of text in the sign<br />
|}<br />
<br />
==== Client Settings ====<br />
<br />
Sent when the player connects, or when settings are changed.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x15<br />
| Locale || String || en_GB<br />
|-<br />
| View distance || Byte || Client-side render distance(chunks)<br />
|-<br />
| Chat flags || Byte || Chat settings. See notes below.<br />
|-<br />
| Chat colours || Bool || "Colours" multiplayer setting<br />
|-<br />
| Displayed skin parts || Unsigned Byte || Unknown<br />
|}<br />
<br />
Chat flags has several values packed into one byte.<br />
<br />
'''Chat Enabled:''' Bits 0-1. 00: Enabled. 01: Commands only. 10: Hidden.<br />
<br />
==== Client Status ====<br />
<br />
Sent when the client is ready to complete login and when the client is ready to respawn after death.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x16<br />
| Action ID || Unsigned Byte || See below<br />
|}<br />
<br />
Action ID values:<br />
{| class="wikitable"<br />
|-<br />
! Action ID !! Name<br />
|-<br />
| 0 || Perform respawn<br />
|-<br />
| 1 || Request stats<br />
|-<br />
| 2 || Open inventory achievement<br />
|}<br />
<br />
==== Plugin Message ====<br />
<br />
Mods and plugins can use this to send their data. Minecraft itself uses a number of [[plugin channel]]s. These internal channels are prefixed with <code>MC|</code>.<br />
<br />
More documentation on this: http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x17 || rowspan=3 | Play || rowspan=3 | Server<br />
| Channel || String || Name of the "channel" used to send the data.<br />
|-<br />
| Data || Byte Array || Any data.<br />
|}<br />
<br />
<br />
==== Spectate ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x18<br />
| Target Player || UUID ||<br />
|}<br />
<br />
==== Resource Pack Status ==== <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x19<br />
| Hash || String || <br />
|-<br />
| Result || VarInt || Successfully loaded: 0, Declined: 1, Failed download: 2, Accepted: 3<br />
|}<br />
<br />
== Data ==<br />
<br />
=== Slot Data ===<br />
<br />
See also [[Slot Data]]<br />
<br />
{| class="wikitable"<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| Block ID || short || -1 for empty slots<br />
|-<br />
| Item count || byte || <br />
|-<br />
| Item damage || short || <br />
|-<br />
| Data || [[NBT]] || Uncompressed NBT data without length prefix. This had previously a short length prefix and was compressed.<br />
|- <br />
|}<br />
<br />
== Login ==<br />
<br />
The login process is as follows:<br />
C->S : Handshake State=2<br />
C->S : Login Start<br />
S->C : Encryption Key Request<br />
(Client Auth)<br />
C->S : Encryption Key Response<br />
(Server Auth, Both enable encryption)<br />
S->C : Login Success<br />
<br />
For unauthenticated and localhost connections there is no encryption.<br />
In that case Login Start is directly followed by Login Success.<br />
<br />
See [[Protocol Encryption]] for details.<br />
<br />
=== Clientbound ===<br />
<br />
==== Encryption Request ====<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x01 || rowspan=5 | Login || rowspan=5 | Client<br />
| Server ID || String || appears to be empty as of 1.7.x<br />
|-<br />
| Length || VarInt || length of public key<br />
|-<br />
| Public Key || Byte array || <br />
|-<br />
| Length || VarInt || length of verify token<br />
|-<br />
| Verify Token || Byte array || <br />
|- <br />
|}<br />
<br />
See [[Protocol Encryption]] for details.<br />
<br />
<br />
==== Set Compression ====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x03<br />
| Threshold || VarInt || Threshold is the max size of a packet before its compressed<br />
|}<br />
<br />
=== Serverbound ===<br />
<br />
==== Encryption Response ====<br />
{| class="wikitable"<br />
! Packet ID !! Category !! Bound To !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x01 || rowspan=4 | Login || rowspan=4 | Server<br />
| Length || VarInt || length of shared secret<br />
|-<br />
| Shared Secret || Byte array || <br />
|-<br />
| Length || VarInt || length of verify token<br />
|-<br />
| Verify Token || Byte array ||<br />
|- <br />
|}<br />
<br />
See [[Protocol Encryption]] for details.</div>Drainedsoulhttps://wiki.vg/index.php?title=Legacy_Mojang_Authentication&diff=5641Legacy Mojang Authentication2014-05-29T19:07:21Z<p>Drainedsoul: "Legacy" from string to boolean</p>
<hr />
<div>Minecraft 1.6 introduced a new authentication scheme called Yggdrasil which completely replaces the [[Legacy_Authentication|previous authentication system]]. Mojang's other game, Scrolls, uses this method of authentication as well. Mojang has said that this Authentication system should be used by everyone for custom logins[https://twitter.com/KrisJelbring/status/453573406341206016], but credentials should never be collected from users[https://twitter.com/KrisJelbring/status/461390585086361600].<br />
<br />
== Request format ==<br />
<br />
All requests to Yggdrasil are made to the following server:<br />
<br />
https://authserver.mojang.com<br />
<br />
Further, they are expected to fulfill the following rules:<br />
<br />
* Are <code>POST</code> requests<br />
* Have the <code>Content-Type</code> header set to <code>application/json</code><br />
* Contain a [http://json.org JSON]-encoded dictionary as payload<br />
<br />
If a request was successful the server will respond with:<br />
<br />
* Status code <code>200</code><br />
* A [http://json.org JSON]-encoded dictionary according to the specifications below<br />
<br />
If however a request fails, the server will respond with:<br />
<br />
* An appropriate, non-200 [http://en.wikipedia.org/wiki/List_of_HTTP_status_codes HTTP status code]<br />
* A [http://json.org JSON]-encoded dictionary following this format:<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"error": "Short description of the error",<br />
"errorMessage": "Longer description which can be shown to the user",<br />
"cause": "Cause of the error" // optional<br />
}<br />
</syntaxhighlight><br />
<br />
== Errors ==<br />
These are some of the errors that can be encountered:<br />
{| class="wikitable"<br />
|-<br />
! Error<br />
! Cause<br />
! Error message<br />
! Notes<br />
|-<br />
| <code>Method Not Allowed</code><br />
|<br />
| The method specified in the request is not allowed for the resource identified by the request URI<br />
| Something other than a POST request was received.<br />
|-<br />
| <code>Not Found</code><br />
|<br />
| The server has not found anything matching the request URI<br />
| Non-existing endpoint was called.<br />
|-<br />
| <code>ForbiddenOperationException</code><br />
| <code>UserMigratedException</code><br />
| Invalid credentials. Account migrated, use e-mail as username.<br />
| <br />
|-<br />
| <code>ForbiddenOperationException</code><br />
| <br />
| Invalid credentials. Invalid username or password.<br />
| <br />
|-<br />
| <code>ForbiddenOperationException</code><br />
| <br />
| Invalid token.<br />
| <code>accessToken</code> was invalid.<br />
|-<br />
| <code>IllegalArgumentException</code><br />
| <br />
| Access token already has a profile assigned.<br />
| Selecting profiles isn't implemented yet.<br />
|-<br />
| <code>IllegalArgumentException</code><br />
| <br />
| credentials can not be null.<br />
| Username/password was not submitted.<br />
|-<br />
| <code>Unsupported Media Type</code><br />
| <br />
| The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method<br />
| Data was not submitted as application/json<br />
|}<br />
<br />
== Authenticate ==<br />
<br />
Authenticates a user using his password.<br />
<br />
=== Endpoint ===<br />
/authenticate<br />
<br />
=== Payload ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"agent": { // defaults to Minecraft<br />
"name": "Minecraft", // For Mojang's other game Scrolls, "Scrolls" should be used<br />
"version": 1 // This number might be increased<br />
// by the vanilla client in the future<br />
},<br />
"username": "mojang account name", // Can be an email address or player name for<br />
// unmigrated accounts<br />
"password": "mojang account password",<br />
"clientToken": "client identifier" // optional<br />
}<br />
</syntaxhighlight><br />
<br />
The <code>clientToken</code> should be a randomly generated identifier and must be identical for each request.<br />
In case it is omitted the server will generate a random token based on Java's [http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html#toString() UUID.toString()] which should then be stored by the client. This will however also invalidate all previously acquired <code>accessToken</code>s for this user across all clients.<br />
<br />
=== Response ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"accessToken": "random access token", // hexadecimal<br />
"clientToken": "client identifier", // identical to the one received<br />
"availableProfiles": [ // only present if the agent field was received<br />
{<br />
"id": "profile identifier", // hexadecimal<br />
"name": "player name",<br />
"legacy": true or false // In practice, this field only appears in the response if true. Default to false.<br />
}<br />
],<br />
"selectedProfile": { // only present if the agent field was received<br />
"id": "profile identifier",<br />
"name": "player name",<br />
"legacy": true or false<br />
}<br />
}<br />
</syntaxhighlight><br />
'''Note:''' If a user wishes to stay logged in on his computer you are strongly advised to store the received <code>accessToken</code> instead of the password itself.<br />
<br />
Currently each account will only have one single profile, multiple profiles per account are however planned in the future. If a user attempts to log into a valid Mojang account with no attached Minecraft license, the authentication will be successful, but the response will not contain a "selectedProfile" field, and the "availableProfiles" array will be empty.<br />
<br />
Some instances in the wild have been observed of Mojang returning a flat "null" for failed refresh attempts against legacy accounts. It's not clear what the actual error tied to the null response is and it is extremely rare, but implementations should be wary of null output from the response.<br />
<br />
== Refresh ==<br />
<br />
Refreshes a valid <code>accessToken</code>. It can be uses to keep a user logged in between gaming sessions and is preferred over storing the user's password in a file (see [[lastlogin]]). <br />
<br />
=== Endpoint ===<br />
/refresh<br />
<br />
=== Payload ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"accessToken": "valid accessToken",<br />
"clientToken": "client identifier" // This needs to be identical to the one used<br />
// to obtain the accessToken in the first place<br />
"selectedProfile": { // optional; sending it will result in an error<br />
"id": "profile identifier", // hexadecimal<br />
"name": "player name"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
Note: The provided <code>accessToken</code> gets invalidated.<br />
<br />
=== Response ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"accessToken": "random access token", // hexadecimal<br />
"clientToken": "client identifier", // identical to the one received<br />
"selectedProfile": {<br />
"id": "profile identifier", // hexadecimal<br />
"name": "player name"<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== Validate ==<br />
<br />
Checks if an <code>accessToken</code> is a valid session token with a currently-active session. Note: this method will not respond successfully to all currently-logged-in sessions, just the most recently-logged-in for each user. It is intended to be used by servers to validate that a user should be connecting (and reject users who have logged in elsewhere since starting Minecraft), NOT to auth that a particular session token is valid for authentication purposes. To authenticate a user by session token, use the refresh verb and catch resulting errors.<br />
<br />
=== Endpoint ===<br />
/validate<br />
<br />
=== Payload ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"accessToken": "valid accessToken",<br />
}<br />
</syntaxhighlight><br />
<br />
=== Response ===<br />
Returns an empty payload if successful.<br />
<br />
== Signout ==<br />
<br />
Invalidates <code>accessToken</code>s using an account's username and password.<br />
<br />
=== Endpoint ===<br />
/signout<br />
<br />
=== Payload ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"username": "mojang account name",<br />
"password": "mojang account password",<br />
}<br />
</syntaxhighlight><br />
<br />
=== Response ===<br />
Returns an empty payload if successful.<br />
<br />
== Invalidate ==<br />
<br />
Invalidates <code>accessToken</code>s using a client/access token pair.<br />
<br />
=== Endpoint ===<br />
/invalidate<br />
<br />
=== Payload ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"accessToken": "valid accessToken",<br />
"clientToken": "client identifier" // This needs to be identical to the one used<br />
// to obtain the accessToken in the first place<br />
}<br />
</syntaxhighlight><br />
<br />
=== Response ===<br />
Returns an empty payload if successful.<br />
<br />
== Joining a Server ==<br />
<br />
See [[Protocol Encryption#Authentication|Protocol Encryption]]<br />
<br />
== Player Information ==<br />
<br />
https://sessionserver.mojang.com/session/minecraft/profile/<uuid><br />
<br />
This will return the player's username plus any additional information about them (e.g. skins). Example: https://sessionserver.mojang.com/session/minecraft/profile/4566e69fc90748ee8d71d7ba5aa00d20<br />
<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]<br />
<br />
=== Response ===<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"id":"profile identifier",<br />
"name":"player name",<br />
"properties":[ <br />
{<br />
"name":"dunno",<br />
"value":"base64 string",<br />
"signature":"base64 string; signed data using Yggdrasil's private key"<br />
}<br />
]<br />
}<br />
</syntaxhighlight><br />
<br />
"value" base64 string decoded:<br />
<syntaxhighlight lang="javascript"><br />
{<br />
"timestamp":"some numbers",<br />
"profileId":"profile identifier",<br />
"profileName":"player name",<br />
"isPublic":"true or false",<br />
"textures":{<br />
"SKIN":{<br />
"url":"player skin URL"<br />
}<br />
"CAPE":{<br />
"url":"player cape URL"<br />
}<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== Players profiles by names ==<br />
<br />
https://api.mojang.com/profiles/minecraft<br />
<br />
Where 'minecraft' - agent name<br />
<br />
This will return players profiles.<br />
<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]<br />
<br />
=== Payload ===<br />
We need to send array of profiles nicknames.<br />
For example:<br />
<syntaxhighlight lang="javascript"><br />
[<br />
"maksimkurb",<br />
"nonExistsPlayer" //Test for non-exists player<br />
]<br />
</syntaxhighlight><br />
<br />
=== Response ===<br />
<syntaxhighlight lang="javascript"><br />
[<br />
{<br />
"id": "0d252b7218b648bfb86c2ae476954d32", //Profile uuid<br />
"name": "maksimkurb", //Profile nickname<br />
"legacy": true, //Profile not migrated to mojang.com? (Only appears, when true)<br />
"demo": true //Game wasn't bought (Only appears, when true)<br />
}<br />
// How we can see, this url return only information about real (exists) profiles.<br />
]<br />
</syntaxhighlight></div>Drainedsoulhttps://wiki.vg/index.php?title=Protocol&diff=5175Protocol2013-11-09T23:26:35Z<p>Drainedsoul: Removed incorrect string/encoding terminology</p>
<hr />
<div>This page presents a dissection of the current stable [http://minecraft.net/game/ Minecraft] protocol. The current pre-release protocol is documented [[Pre-release_protocol|elsewhere]]. The protocol for Pocket Minecraft is substantially different, and is documented at [[Pocket Minecraft Protocol]].<br />
<br />
If you're having trouble, check out the [[Protocol_FAQ|FAQ]] or ask for help in the IRC channel ([irc://irc.freenode.net/mcdevs #mcdevs on irc.freenode.net]).<br />
<br />
'''Note:''' While you may use the contents of this page without restriction to create servers, clients, bots, etc… you still need to provide attribution to #mcdevs if you copy any of the contents of this page for publication elsewhere.<br />
<br />
{{Warning|As of 1.7 strings are now UTF-8 (prefixed with a VarInt giving the string's length in bytes) instead of UTF-16.}}<br />
<br />
{| class="wikitable"<br />
|-<br />
! Term<br />
! Definition<br />
|-<br />
| Player<br />
| When used in the singular, Player always refers to the client connected to the server<br />
|-<br />
| Entity<br />
| Entity refers to any item, player, mob, minecart or boat in the world. This definition is subject to change as Notch extends the protocol<br />
|-<br />
| EID<br />
| An EID - or Entity ID - is a unique 4-byte integer used to identify a specific entity<br />
|-<br />
| XYZ<br />
| In this document, the axis names are the same as those used by Notch. Y points upwards, X points South, and Z points West.<br />
|-<br />
!colspan="2"|See also: [[Data types]], [[Units of Measurement]]<br />
|}<br />
<br />
The changes between versions may be viewed at [[Protocol History]]<br />
<br />
== Packets ==<br />
=== Protocol Version ===<br />
1.7.2 - 4<br />
<br />
== Packet format ==<br />
<br />
{| class="wikitable"<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| Length || VarInt || Includes the packet id's length<br />
|-<br />
| Packet ID || VarInt ||<br />
|-<br />
| Data || ||<br />
|}<br />
<br />
== Handshaking ==<br />
<br />
=== Serverbound ===<br />
<br />
==== Handshake ====<br />
This causes the server to switch into the target state.<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x00<br />
| Protocol Version || VarInt || (4 as of 1.7.2)<br />
|-<br />
| Server Address (hostname or IP) || String || localhost<br />
|- <br />
| Server Port || Unsigned Short|| 25565<br />
|-<br />
| Next state || VarInt || 1 for status, 2 for login<br />
|}<br />
<br />
== Play ==<br />
<br />
=== Clientbound ===<br />
<br />
==== Keep Alive ====<br />
<br />
The server will frequently send out a keep-alive, each containing a random ID. The client must respond with the same packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00<br />
| Keep Alive ID || Int ||<br />
|}<br />
<br />
<br />
==== Join Game ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x01<br />
| Entity ID || Int || The player's Entity ID<br />
|-<br />
| Gamemode || Unsigned Byte || 0: survival, 1: creative, 2: adventure. Bit 3 (0x8) is the hardcore flag<br />
|-<br />
| Dimension || Byte || -1: nether, 0: overworld, 1: end<br />
|-<br />
| Difficulty || Unsigned Byte || 0 thru 3 for Peaceful, Easy, Normal, Hard<br />
|-<br />
| Max Players || Unsigned Byte || Used by the client to draw the player list<br />
|-<br />
| Level Type || String || default, flat, largeBiomes, amplified, default_1_1<br />
|}<br />
{{Warning|If the Dimension isn't valid then the client will crash}}<br />
<br />
==== Chat Message ==== <br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x02<br />
| JSON Data || String || https://gist.github.com/thinkofdeath/e882ce057ed83bac0a1c , Limited to 32767 bytes<br />
|}<br />
{{Warning|Malformed JSON will disconnect the client}}<br />
<br />
==== Time Update ====<br />
<br />
Time is based on ticks, where 20 ticks happen every second. There are 24000 ticks in a day, making Minecraft days exactly 20 minutes long.<br />
<br />
The time of day is based on the timestamp modulo 24000. 0 is sunrise, 6000 is noon, 12000 is sunset, and 18000 is midnight.<br />
<br />
The default SMP server increments the time by <code>20</code> every second.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x03<br />
| Age of the world || Long || In ticks; not changed by server commands<br />
|-<br />
| Time of day || Long || The world (or region) time, in ticks. If negative the sun will stop moving at the Math.abs of the time<br />
|}<br />
<br />
==== Entity Equipment ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x04<br />
| EntityID || Int || Entity's ID<br />
|-<br />
| Slot || Short || Equipment slot: 0=held, 1-4=armor slot (1 - boots, 2 - leggings, 3 - chestplate, 4 - helmet)<br />
|-<br />
| Item || [[Slot_Data|Slot]] || Item in slot format<br />
|}<br />
<br />
==== Spawn Position ====<br />
<br />
Sent by the server after login to specify the coordinates of the spawn point (the point at which players spawn at, and which the compass points to). It can be sent at any time to update the point compasses point at.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x05<br />
| X || Int || Spawn X in block coordinates<br />
|-<br />
| Y || Int || Spawn Y in block coordinates<br />
|-<br />
| Z || Int || Spawn | in block coordinates<br />
|}<br />
<br />
==== Update Health ====<br />
<br />
Sent by the server to update/set the health of the player it is sent to.<br />
<br />
Food saturation acts as a food "overcharge". Food values will not decrease while the saturation is over zero. Players logging in automatically get a saturation of 5.0. Eating food increases the saturation as well as the food bar.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x06<br />
| Health || Float || 0 or less = dead, 20 = full HP<br />
|-<br />
| Food || Short || 0 - 20<br />
|- <br />
| Food Saturation || Float || Seems to vary from 0.0 to 5.0 in integer increments<br />
|}<br />
<br />
==== Respawn ====<br />
<br />
To change the player's dimension (overworld/nether/end), send them a respawn packet with the appropriate dimension, followed by prechunks/chunks for the new dimension, and finally a position and look packet. You do not need to unload chunks, the client will do it automatically.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x07<br />
| Dimension || Int || -1: The Nether, 0: The Overworld, 1: The End<br />
|-<br />
| Difficulty || Unsigned Byte || 0 thru 3 for Peaceful, Easy, Normal, Hard.<br />
|-<br />
| Gamemode || Unsigned Byte || 0: survival, 1: creative, 2: adventure. The hardcore flag is not included<br />
|-<br />
| Level Type || String || Same as Join Game<br />
|}<br />
{{Warning|If the Dimension isn't valid then the client will crash}}<br />
<br />
{{Warning|Avoid changing player's dimension to same dimension they were already in, weird bugs can occur i.e. such player will be unable to attack other players in new world (fixes after their death and respawn)}}<br />
<br />
==== Player Position And Look ==== <br />
<br />
Updates the players position on the server. <br />
If the distance between the last known position of the player on the server and the new position set by this packet is greater than 100 units will result in the client being kicked for "You moved too quickly :( (Hacking?)"<br />
Also if the fixed-point number of X or Z is set greater than <code>3.2E7D</code> the client will be kicked for "Illegal position"<br />
<br />
Yaw is measured in degrees, and does not follow classical trigonometry rules. The unit circle of yaw on the xz-plane starts at (0, 1) and turns backwards towards (-1, 0), or in other words, it turns clockwise instead of counterclockwise. Additionally, yaw is not clamped to between 0 and 360 degrees; any number is valid, including negative numbers and numbers greater than 360.<br />
<br />
Pitch is measured in degrees, where 0 is looking straight ahead, -90 is looking straight up, and 90 is looking straight down.<br />
<br />
You can get a unit vector from a given yaw/pitch via:<br />
x = -cos(pitch) * sin(yaw)<br />
y = -sin(pitch)<br />
z = cos(pitch) * cos(yaw)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6| 0x08<br />
| X || Double || Absolute position<br />
|-<br />
| Y || Double || Absolute position<br />
|-<br />
| Z || Double || Absolute position<br />
|-<br />
| Yaw || Float || Absolute rotation on the X Axis, in degrees<br />
|-<br />
| Pitch || Float || Absolute rotation on the Y Axis, in degrees<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Held Item Change ==== <br />
<br />
Sent to change the player's slot selection<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x09<br />
| Slot || Byte || The slot which the player has selected (0-8)<br />
|}<br />
<br />
==== Use Bed ==== <br />
<br />
This packet tells that a player goes to bed.<br />
<br />
The client with the matching Entity ID will go into bed mode.<br />
<br />
This Packet is sent to all nearby players including the one sent to bed.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x0A<br />
| Entity ID || Int || Player ID<br />
|-<br />
| X || Int || Bed headboard X as block coordinate<br />
|-<br />
| Y || Unsigned Byte || Bed headboard Y as block coordinate<br />
|-<br />
| Z || Int || Bed headboard Z as block coordinate<br />
|}<br />
<br />
==== Animation ====<br />
<br />
Sent whenever an entity should change animation.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x0B<br />
| Entity ID || VarInt || Player ID<br />
|-<br />
| Animation || Unsigned Byte || Animation ID<br />
|}<br />
<br />
Animation can be one of the following values:<br />
<br />
{| class="wikitable"<br />
! ID !! Animation<br />
|-<br />
| 0 || Swing arm<br />
|-<br />
| 1 || Damage animation<br />
|-<br />
| 2 || Leave bed<br />
|-<br />
| 3 || Eat food<br />
|-<br />
| 4 || Critical effect<br />
|-<br />
| 5 || Magic critical effect<br />
|-<br />
| 102 || (unknown)<br />
|-<br />
| 104 || Crouch<br />
|-<br />
| 105 || Uncrouch<br />
|}<br />
<br />
==== Spawn Player ====<br />
<br />
This packet is sent by the server when a player comes into visible range, '''not''' when a player joins.<br />
<br />
Servers can, however, safely spawn player entities for players not in visible range. The client appears to handle it correctly.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=10 | 0x0C<br />
| Entity ID || VarInt || Player's Entity ID<br />
|-<br />
| Player UUID || String || Player's UUID<br />
|-<br />
| Player Name || String || Player's Name<br />
|-<br />
| X || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Y || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Z || Int || Player X as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Yaw || Byte || Player rotation as a packed byte<br />
|-<br />
| Pitch || Byte || Player rotation as a packet byte<br />
|-<br />
| Current Item || Short || The item the player is currently holding. Note that this should be 0 for "no item", unlike -1 used in other packets. A negative value crashes clients.<br />
|-<br />
| Metadata || [[Entities#Entity_Metadata_Format|Metadata]] || The client will crash if no metadata is sent<br />
|}<br />
{{Warning|The client will crash if no metadata is sent}}<br />
<br />
==== Collect Item ====<br />
<br />
Sent by the server when someone picks up an item lying on the ground - its sole purpose appears to be the animation of the item flying towards you. It doesn't destroy the entity in the client memory, and it doesn't add it to your inventory. The server only checks for items to be picked up after each Player Position and [Player Position & Look packet sent by the client.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x0D<br />
| Collected Entity ID || Int ||<br />
|- <br />
| Collector Entity ID || Int ||<br />
|}<br />
<br />
==== Spawn Object ====<br />
<br />
Sent by the server when an Object/Vehicle is created.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=8| 0x0E<br />
| Entity ID || VarInt || Entity ID of the object<br />
|-<br />
| Type || Byte || The type of object (See [[Entities#Objects|Objects]])<br />
|-<br />
| X || Int || X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Y || Int || Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Z || Int || Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Pitch || Byte || The pitch in steps of 2p/256<br />
|-<br />
| Yaw || Byte || The yaw in steps of 2p/256<br />
|-<br />
| Data || [[Object_Data|Object Data]] ||<br />
|}<br />
<br />
==== Spawn Mob ====<br />
<br />
Sent by the server when a Mob Entity is Spawned<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=12 | 0x0F<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Type || Unsigned Byte || The type of mob. See [[Entities#Mobs|Mobs]]<br />
|-<br />
| X || Int || X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Y || Int || Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Z || Int || Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Pitch || Byte || The pitch in steps of 2p/256<br />
|-<br />
| Head Pitch || Byte || The pitch in steps of 2p/256<br />
|-<br />
| Yaw || Byte || The yaw in steps of 2p/256<br />
|-<br />
| Velocity X || Short ||<br />
|-<br />
| Velocity Y || Short ||<br />
|-<br />
| Velocity Z || Short ||<br />
|-<br />
| Metadata || [[Entities#Entity_Metadata_Format|Metadata]] ||<br />
|}<br />
<br />
==== Spawn Painting ====<br />
<br />
This packet shows location, name, and type of painting.<br />
<br />
Calculating the center of an image: given a (width x height) grid of cells, with (0, 0) being the top left corner, the center is (max(0, width / 2 - 1), height / 2). E.g.<br />
<br />
2x1 (1, 0)<br />
4x4 (1, 2)<br />
<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x10<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| Title || String || Name of the painting. Max length 13<br />
|-<br />
| X || Int || Center X coordinate<br />
|-<br />
| Y || Int || Center Y coordinate<br />
|-<br />
| Z || Int || Center Z coordinate<br />
|-<br />
| Direction || Int || Direction the painting faces (0 -z, 1 -x, 2 +z, 3 +x)<br />
|}<br />
<br />
==== Spawn Experience Orb ====<br />
<br />
Spawns one or more experience orbs.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x11<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| X || Int || X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Y || Int || Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Z || Int || Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]] <br />
|-<br />
| Count || Short || The amount of experience this orb will reward once collected<br />
|}<br />
<br />
==== Entity Velocity ====<br />
<br />
Velocity is believed to be in units of 1/8000 of a block per server tick (50ms);<br />
for example, -1343 would move (-1343 / 8000) = −0.167875 blocks per tick (or −3,3575 blocks per second).<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x12<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Velocity X || Short || Velocity on the X axis<br />
|-<br />
| Velocity Y || Short || Velocity on the Y axis<br />
|-<br />
| Velocity Z || Short || Velocity on the Z axis<br />
|}<br />
<br />
==== Destroy Entities====<br />
<br />
Sent by the server when an list of Entities is to be destroyed on the client.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x13<br />
| Count || Byte || Length of following array<br />
|-<br />
| Entity IDs || Array of Int || The list of entities of destroy <br />
|}<br />
<br />
==== Entity ====<br />
<br />
Most entity-related packets are subclasses of this packet. When sent from the server to the client, it may initialize the entry.<br />
<br />
For player entities, either this packet or any move/look packet is sent every game tick.<br />
So the meaning of this packet is basically that the entity did not move/look since the last such packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x14<br />
| Entity ID || Int || Entity's ID<br />
|}<br />
<br />
==== Entity Relative Move ====<br />
<br />
This packet is sent by the server when an entity moves less then 4 blocks; if an entity moves more than 4 blocks Entity Teleport should be sent instead.<br />
<br />
This packet allows at most four blocks movement in any direction, because byte range is from -128 to 127.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4| 0x15<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| DX || Byte || Change in X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DY || Byte || Change in Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DZ || Byte || Change in Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|}<br />
<br />
==== Entity Look ====<br />
<br />
This packet is sent by the server when an entity rotates. Example: "Yaw" field 64 means a 90 degree turn.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x16<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|}<br />
<br />
==== Entity Look and Relative Move ====<br />
<br />
This packet is sent by the server when an entity rotates and moves.<br />
Since a byte range is limited from -128 to 127, and movement is offset of fixed-point numbers,<br />
this packet allows at most four blocks movement in any direction. (-128/32 == -4)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x17<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| DX || Byte || Change in X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DY || Byte || Change in Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| DZ || Byte || Change in Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|}<br />
<br />
==== Entity Teleport ====<br />
<br />
This packet is sent by the server when an entity moves more than 4 blocks.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x18<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| X || Int || X position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Y || Int || Y position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Z || Int || Z position as a [[Data_Types#Fixed-point_numbers|Fixed-Point number]]<br />
|-<br />
| Yaw || Byte || The X Axis rotation as a fraction of 360<br />
|-<br />
| Pitch || Byte || The Y Axis rotation as a fraction of 360<br />
|}<br />
<br />
==== Entity Head Look ====<br />
<br />
Changes the direction an entity's head is facing.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x19<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Head Yaw || Byte || Head yaw in steps of 2p/256<br />
|}<br />
<br />
==== Entity Status ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x1A<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Entity Status || Byte || See below<br />
|}<br />
<br />
{| class="wikitable"<br />
|-<br />
! Entity Status !! Meaning<br />
|-<br />
| 2 || Entity hurt<br />
|-<br />
| 3 || Entity dead<br />
|-<br />
| 6 || Wolf taming<br />
|-<br />
| 7 || Wolf tamed<br />
|-<br />
| 8 || Wolf shaking water off itself<br />
|-<br />
| 9 || (of self) Eating accepted by server<br />
|-<br />
| 10 || Sheep eating grass<br />
|-<br />
| 11 || Iron Golem handing over a rose<br />
|-<br />
| 12 || Spawn "heart" particles near a villager<br />
|-<br />
| 13 || Spawn particles indicating that a villager is angry and seeking revenge<br />
|-<br />
| 14 || Spawn happy particles near a villager<br />
|-<br />
| 15 || Spawn a "magic" particle near the Witch<br />
|-<br />
| 16 || Zombie converting into a villager by shaking violently (unused in recent update)<br />
|-<br />
| 17 || A firework exploding<br />
|}<br />
<br />
==== Attach Entity ====<br />
<br />
This packet is sent when a player has been attached to an entity (e.g. Minecart)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x1B<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Vehicle ID || Int || Vechicle's Entity ID<br />
|-<br />
| Leash || Bool || If true leashes the entity to the vehicle<br />
|}<br />
<br />
==== Entity Metadata ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x1C<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Metadata || [[Entities#Entity_Metadata_Format|Metadata]] || <br />
|}<br />
<br />
==== Entity Effect ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x1D<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Effect ID || Byte || See [[http://www.minecraftwiki.net/wiki/Potion_effect#Parameters]]<br />
|-<br />
| Amplifier || Byte || <br />
|-<br />
| Duration || Short ||<br />
|}<br />
<br />
==== Remove Entity Effect ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x1E<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Effect ID || Byte ||<br />
|}<br />
<br />
==== Set Experience ====<br />
<br />
Sent by the server when the client should change experience levels.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x1F<br />
| Experience bar || Float || Between 0 and 1<br />
|-<br />
| Level || Short ||<br />
|-<br />
| Total Experience || Short ||<br />
|}<br />
<br />
==== Entity Properties ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3 | 0x20<br />
| Entity ID || Int || Entity's ID<br />
|-<br />
| Count || Int || Length of following array<br />
|-<br />
| Properties || Array of Property Data ||<br />
|}<br />
<br />
'''Property Data''' structure:<br />
{| class="wikitable"<br />
|-<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| Key || String || <br />
|-<br />
| Value || Double || <br />
|-<br />
| List Length || Short || Number of list elements that follow.<br />
|-<br />
| Modifiers || Array of Modifier Data || http://www.minecraftwiki.net/wiki/Attribute#Modifiers<br />
|}<br />
<br />
Known key values:<br />
{| class="wikitable"<br />
|-<br />
! Key !! Default !! Min !! Max !! Label<br />
|-<br />
| generic.maxHealth || 20.0 || 0.0 || Double.MaxValue || Max Health<br />
|-<br />
| generic.followRange || 32.0 || 0.0 || 2048.0 || Follow Range<br />
|-<br />
| generic.knockbackResistance || 0.0 || 0.0 || 1.0 || Knockback Resistance<br />
|-<br />
| generic.movementSpeed || 0.699999988079071 || 0.0 || Double.MaxValue || Movement Speed<br />
|-<br />
| generic.attackDamage || 2.0 || 0.0 || Double.MaxValue || <br />
|-<br />
| horse.jumpStrength || 0.7 || 0.0 || 2.0 || Jump Strength<br />
|-<br />
| zombie.spawnReinforcements || 0.0 || 0.0 || 1.0 || Spawn Reinforcements Chance<br />
|}<br />
<br />
'''Modifier Data''' structure:<br />
{| class="wikitable"<br />
|-<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
| UUID || 128-bit integer ||<br />
|-<br />
| Amount || Double ||<br />
|-<br />
| Operation || Byte ||<br />
|}<br />
<br />
==== Chunk Data ====<br />
<br />
Chunks are not unloaded by the client automatically. To unload chunks, send this packet with ground-up continuous=true and no 16^3 chunks (eg. primary bit mask=0). The server does not send skylight information for nether-chunks, it's up to the client to know if the player is currently in the nether. You can also infer this information from the primary bitmask and the amount of uncompressed bytes sent.<br />
<br />
See also: [[SMP Map Format]]<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7 | 0x21<br />
| Chunk X || Int || Chunk X coordinate<br />
|-<br />
| Chunk Z || Int || Chunk Z coordinate<br />
|-<br />
| Ground-Up continuous || Boolean || This is True if the packet represents all sections in this vertical column, where the primary bit map specifies exactly which sections are included, and which are air<br />
|-<br />
| Primary bit map || Unsigned Short || Bitmask with 1 for every 16x16x16 section which data follows in the compressed data.<br />
|-<br />
| Add bit map || Unsigned Short || Same as above, but this is used exclusively for the 'add' portion of the payload<br />
|- <br />
| Compressed size || Int || Size of compressed chunk data<br />
|-<br />
| Compressed data || Byte array || The chunk data is compressed using Zlib Deflate<br />
|}<br />
<br />
==== Multi Block Change ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x22<br />
| Chunk X || Int || Chunk X coordinate<br />
|-<br />
| Chunk Z || Int || Chunk Z Coordinate<br />
|-<br />
| Record count || Short || The number of blocks affected<br />
|-<br />
| Data size || Int || The total size of the data, in bytes. Should always be 4*record count<br />
|-<br />
| Records || Array of Records || <br />
|}<br />
<br />
'''Record'''<br />
{| class="wikitable"<br />
|-<br />
! Bit mask !! Width !! Meaning<br />
|-<br />
| 00 00 00 0F || 4 bits || Block metadata<br />
|-<br />
| 00 00 FF F0 || 12 bits || Block ID<br />
|-<br />
| 00 FF 00 00 || 8 bits || Y co-ordinate<br />
|-<br />
| 0F 00 00 00 || 4 bits || Z co-ordinate, relative to chunk<br />
|-<br />
| F0 00 00 00 || 4 bits || X co-ordinate, relative to chunk<br />
|}<br />
<br />
==== Block Change ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x23<br />
| X || Int || Block X Coordinate<br />
|-<br />
| Y || Unsigned Byte || Block Y Coordinate<br />
|-<br />
| Z || Int || Block Z Coordinate<br />
|-<br />
| Block Type || VarInt || The new block type for the block<br />
|-<br />
| Block Data || Unsigned Byte || The new data for the block<br />
|}<br />
<br />
==== Block Action ====<br />
<br />
This packet is used for a number of things:<br />
* <div class="li">Chests opening and closing<br />
* Pistons pushing and pulling<br />
* Note blocks playing<br />
<br />
See Also: [[Block Actions]] <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=6 | 0x24<br />
| X || Int || Block X Coordinate<br />
|-<br />
| Y || Short || Block Y Coordinate<br />
|-<br />
| Z || Int || Block Z Coordinate<br />
|-<br />
| Byte 1 || Unsigned Byte || Varies depending on block - see [[Block_Actions]]<br />
|-<br />
| Byte 2 || Unsigned Byte || Varies depending on block - see [[Block_Actions]]<br />
|-<br />
| Block Type || VarInt || The block type for the block<br />
|}<br />
<br />
==== Block Break Animation ====<br />
<br />
0-9 are the displayable destroy stages and each other number means that there is no animation on this coordinate.<br />
<br />
You can also set an animation to air! The animation will still be visible.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x25<br />
| Entity ID || VarInt || Entity's ID<br />
|-<br />
| X || Int || rowspan=3 | Block Position<br />
|-<br />
| Y || Int<br />
|-<br />
| Z || Int<br />
|-<br />
| Destroy Stage || Byte || 0 - 9<br />
|}<br />
<br />
==== Map Chunk Bulk ====<br />
<br />
See also: [[SMP Map Format]]<br />
<br />
To reduce the number of bytes this packet is used to send chunks together for better compression results.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x26<br />
| Chunk column count || Short || The number of chunk in this packet<br />
|-<br />
| Data length || Int || The size of the data field<br />
|-<br />
| Sky light sent || Bool || Whether or not the chunk data contains a light nibble array. This is true in the main world, false in the end + nether<br />
|-<br />
| Data || Byte Array || Compressed chunk data<br />
|-<br />
| Meta information || Meta || See below <br />
|}<br />
<br />
'''Meta'''<br />
{| class="wikitable"<br />
! Field Name !! Field Type !! Notes<br />
|-<br />
|Chunk X || Int || The X Coordinate of the chunk<br />
|-<br />
|Chunk Z || Int || The Z Coordinate of the chunk<br />
|-<br />
|Primary bitmap || Unsigned Short || A bitmap which specifies which sections are not empty in this chunk<br />
|-<br />
|Add bitmap || Unsigned Short || A bitmap which specifies which sections need add information because of very high block ids. not yet used<br />
|}<br />
{{Warning|If you send this packet to update area surrounding player in the middle of the game, entities within the updated area may become unattackable}}<br />
<br />
==== Explosion ====<br />
<br />
Sent when an explosion occurs (creepers, TNT, and ghast fireballs).<br />
<br />
Each block in Records is set to air. Coordinates for each axis in record is int(X) + record.x<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="9" | 0x27<br />
| X || Float ||<br />
|-<br />
| Y || Float ||<br />
|-<br />
| Z || Float ||<br />
|-<br />
| Radius || Float || Currently unused in the client<br />
|-<br />
| Record count || Int || This is the count, not the size. The size is 3 times this value.<br />
|-<br />
| Records || (Byte, Byte, Byte) × count || Each record is 3 signed bytes long, each bytes are the XYZ (respectively) offsets of affected blocks.<br />
|-<br />
| Player Motion X || Float || X velocity of the player being pushed by the explosion<br />
|-<br />
| Player Motion Y || Float || Y velocity of the player being pushed by the explosion<br />
|-<br />
| Player Motion Z || Float || Z velocity of the player being pushed by the explosion<br />
|}<br />
<br />
==== Effect ====<br />
<br />
Sent when a client is to play a sound or particle effect.<br />
<br />
By default, the minecraft client adjusts the volume of sound effects based on distance. The final boolean field is used to disable this, and instead the effect is played from 2 blocks away in the correct direction. Currently this is only used for effect 1013 (mob.wither.spawn), and is ignored for any other value by the client.<br />
<br />
===== Effects =====<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x28<br />
| Effect ID || Int || The ID of the effect, see below.<br />
|-<br />
| X || Int || The X location of the effect multiplied by 8<br />
|-<br />
| Y || Byte || The Y location of the effect multiplied by 8<br />
|-<br />
| Z || Int || The Z location of the effect multiplied by 8<br />
|-<br />
| Data || Int || Extra data for certain effects, see below.<br />
|-<br />
| Disable relative volume || Bool || See above<br />
|}<br />
<br />
{| class="wikitable"<br />
! ID !! Name<br />
|-<br />
| colspan=2 | '''Sound'''<br />
|-<br />
| 1000|| <code>random.click</code><br />
|-<br />
| 1001|| <code>random.click</code><br />
|-<br />
| 1002|| <code>random.bow</code><br />
|-<br />
| 1003|| <code>random.door_open</code> or <code>random.door_close</code> (50/50 chance)<br />
|-<br />
| 1004|| <code>random.fizz</code><br />
|-<br />
| 1005|| Play a music disc. '''Data''' [http://www.minecraftwiki.net/wiki/Music_Discs Record ID]<br />
|-<br />
| ''(1006 not assigned)'' ||<br />
|-<br />
| 1007|| <code>mob.ghast.charge</code><br />
|-<br />
| 1008|| <code>mob.ghast.fireball</code><br />
|-<br />
| 1009|| <code>mob.ghast.fireball</code>, but with a lower volume.<br />
|-<br />
| 1010|| <code>mob.zombie.wood</code><br />
|-<br />
| 1011|| <code>mob.zombie.metal</code><br />
|-<br />
| 1012|| <code>mob.zombie.woodbreak</code><br />
|-<br />
| 1013|| <code>mob.wither.spawn</code><br />
|-<br />
| 1014|| <code>mob.wither.shoot</code><br />
|-<br />
| 1015|| <code>mob.bat.takeoff</code><br />
|-<br />
| 1016|| <code>mob.zombie.infect</code><br />
|-<br />
| 1017|| <code>mob.zombie.unfect</code><br />
|-<br />
| 1018|| <code>mob.enderdragon.end</code><br />
|-<br />
| 1020|| <code>random.anvil_break</code><br />
|-<br />
| 1021|| <code>random.anvil_use</code><br />
|-<br />
| 1022|| <code>random.anvil_land</code><br />
|-<br />
| colspan=2 | '''Particle'''<br />
|-<br />
| 2000|| Spawns 10 smoke particles, e.g. from a fire. '''Data''' direction, see below<br />
|-<br />
| 2001|| Block break. '''Data''' [http://www.minecraftwiki.net/wiki/Data_values Block ID]<br />
|-<br />
| 2002|| Splash potion. Particle effect + glass break sound. '''Data''' [http://www.lb-stuff.com/Minecraft/PotionDataValues1.9pre3.txt Potion ID]<br />
|-<br />
| 2003|| Eye of ender entity break animation - particles and sound<br />
|-<br />
| 2004|| Mob spawn particle effect: smoke + flames<br />
|-<br />
| 2005|| Spawn "happy villager" effect (hearts).<br />
|}<br />
<br />
Smoke directions:<br />
<br />
{| class="wikitable"<br />
! ID !! Direction<br />
|-<br />
| 0 || South - East<br />
|-<br />
| 1 || South<br />
|-<br />
| 2 || South - West<br />
|-<br />
| 3 || East<br />
|-<br />
| 4 || (Up or middle ?)<br />
|-<br />
| 5 || West<br />
|-<br />
| 6 || North - East<br />
|-<br />
| 7 || North<br />
|-<br />
| 8 || North - West<br />
|}<br />
<br />
==== Sound Effect ====<br />
<br />
Used to play a sound effect on the client.<br />
<br />
All known sound effect names can be seen [https://github.com/SirCmpwn/Craft.Net/blob/master/source/Craft.Net.Common/SoundEffect.cs here].<br />
<br />
Custom sounds made be added by resource packs<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="7" | 0x29<br />
| Sound name || String || <br />
|-<br />
| Effect position X || Int || Effect X multiplied by 8<br />
|-<br />
| Effect position Y || Int || Effect Y multiplied by 8<br />
|-<br />
| Effect position Z || Int || Effect Z multiplied by 8<br />
|-<br />
| Volume || Float || 1 is 100%, can be more<br />
|-<br />
| Pitch || Unsigned Byte || 63 is 100%, can be more<br />
|}<br />
<br />
==== Particle ====<br />
<br />
Displays the named particle<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="9" | 0x2A<br />
| Particle name || String || The name of the particle to create. A list can be found [https://gist.github.com/thinkofdeath/5110835 here]<br />
|-<br />
| X || Float || X position of the particle<br />
|-<br />
| Y || Float || Y position of the particle<br />
|-<br />
| Z || Float || Z position of the particle<br />
|-<br />
| Offset X || Float || This is added to the X position after being multiplied by random.nextGaussian() <br />
|-<br />
| Offset Y || Float || This is added to the Y position after being multiplied by random.nextGaussian() <br />
|-<br />
| Offset Z || Float || This is added to the Z position after being multiplied by random.nextGaussian() <br />
|-<br />
| Particle data || Float || The data of each particle<br />
|-<br />
| Number of particles || Int || The number of particles to create<br />
|}<br />
<br />
==== Change Game State ====<br />
<br />
It appears when a bed can't be used as a spawn point and when the rain state changes. <br />
<br />
The class has an array of strings linked to reason codes 0, 1, 2, and 3 but only the codes for 1 and 2 are null.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x2B<br />
| Reason || Unsigned Byte ||<br />
|-<br />
| Value || Float || Depends on reason<br />
|}<br />
<br />
'''Reason codes'''<br />
<br />
{| class="wikitable"<br />
! Code !! Effect !! Notes<br />
|-<br />
| 0 || Invalid Bed || "tile.bed.notValid"<br />
|-<br />
| 1 || End raining || <br />
|-<br />
| 2 || Begin raining || <br />
|-<br />
| 3 || Change game mode || "gameMode.changed" 0 - Survival, 1 - Creative, 2 - Adventure <br />
|-<br />
| 4 || Enter credits ||<br />
|-<br />
| 5 || Demo messages || 0 - Show welcome to demo screen, 101 - Tell movement controls, 102 - Tell jump control, 103 - Tell inventory control<br />
|- <br />
| 6 || Bow hit sound ||<br />
|-<br />
| 7 || Fade value || The current darkness value. 1 = Dark, 0 = Bright, Setting the value higher causes the game to change color and freeze<br />
|-<br />
| 8 || Fade time || Time in ticks for the sky to fade<br />
|}<br />
<br />
==== Spawn Global Entity ====<br />
<br />
With this packet, the server notifies the client of thunderbolts striking within a 512 block radius around the player. The coordinates specify where exactly the thunderbolt strikes.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="5" | 0x2C<br />
| Entity ID || VarInt || The entity ID of the thunderbolt<br />
|-<br />
| Type || Byte || The global entity type, currently always 1 for thunderbolt.<br />
|-<br />
| X || Int || Thunderbolt X a [[Data_Types#Fixed-point_numbers|fixed-point number]]<br />
|-<br />
| Y || Int || Thunderbolt Y a [[Data_Types#Fixed-point_numbers|fixed-point number]]<br />
|-<br />
| Z || Int || Thunderbolt Z a [[Data_Types#Fixed-point_numbers|fixed-point number]]<br />
|}<br />
<br />
==== Open Window ====<br />
<br />
This is sent to the client when it should open an inventory, such as a chest, workbench, or furnace. This message is not sent anywhere for clients opening their own inventory.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x2D<br />
| Window id || Unsigned Byte || A unique id number for the window to be displayed. Notchian server implementation is a counter, starting at 1.<br />
|-<br />
| Inventory Type || Unsigned Byte || The window type to use for display. Check below<br />
|-<br />
| Window title || String || The title of the window.<br />
|-<br />
| Number of Slots || Unsigned Byte || Number of slots in the window (excluding the number of slots in the player inventory).<br />
|-<br />
| Use provided window title || Bool || If false, the client will look up a string like "window.minecart". If true, the client uses what the server provides.<br />
|-<br />
| Entity ID || Int || EntityHorse's entityId. Only sent when window type is equal to 11 (AnimalChest).<br />
|}<br />
<br />
See [[Inventory#Windows|inventory windows]] for further information.<br />
<br />
==== Close Window ====<br />
<br />
This packet is sent from the server to the client when a window is forcibly closed, such as when a chest is destroyed while it's open.<br />
<br />
Note, notchian clients send a close window message with window id 0 to close their inventory even though there is never an Open Window message for inventory. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| 0x2E<br />
| Window ID || Unsigned Byte || This is the id of the window that was closed. 0 for inventory.<br />
|}<br />
<br />
==== Set Slot ====<br />
<br />
Sent by the server when an item in a slot (in a window) is added/removed.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x2F<br />
| Window ID || Unsigned Byte<br />
| The window which is being updated. 0 for player inventory. Note that all known window types include the player inventory. This packet will only be sent for the currently opened window while the player is performing actions, even if it affects the player inventory. After the window is closed, a number of these packets are sent to update the player's inventory window (0).<br />
|-<br />
| Slot || Short || The slot that should be updated<br />
|-<br />
| Slot data || [[Slot_Data|Slot]] ||<br />
|}<br />
<br />
==== Window Items ====<br />
<br />
[[File:Inventory-slots.png|thumb|The inventory slots]]<br />
<br />
Sent by the server when an item in a slot (in a window) is added/removed. This includes the main inventory, equipped armour and crafting slots. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x30<br />
| Window ID || Unsigned Byte || The id of window which items are being sent for. 0 for player inventory.<br />
|-<br />
| Count || Short || The number of slots (see below)<br />
|-<br />
| Slot data || Array of [[Slot_Data|Slot]]s ||<br />
|}<br />
<br />
See [[Inventory#Windows|inventory windows]] for further information about how slots are indexed.<br />
<br />
==== Window Property ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x31<br />
| Window ID || Unsigned Byte || The id of the window.<br />
|-<br />
| Property || Short || Which property should be updated.<br />
|-<br />
| Value || Short || The new value for the property.<br />
|}<br />
<br />
'''Furnace'''<br />
<br />
Properties:<br />
<br />
* 0: Progress arrow<br />
* 1: Fire icon (fuel)<br />
<br />
Values:<br />
<br />
* 0-200 for progress arrow<br />
* 0-200 for fuel indicator<br />
<br />
Ranges are presumably in in-game ticks<br />
<br />
'''Enchantment Table'''<br />
<br />
Properties: 0, 1 or 2 depending on the "enchantment slot" being given.<br />
<br />
Values: The enchantment's level.<br />
<br />
==== Confirm Transaction ====<br />
<br />
A packet from the server indicating whether a request from the client was accepted, or whether there was a conflict (due to lag). This packet is also sent from the client to the server in response to a server transaction rejection packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x32<br />
| Window ID || Unsigned Byte || The id of the window that the action occurred in.<br />
|-<br />
| Action number || Short || Every action that is to be accepted has a unique number. This field corresponds to that number.<br />
|-<br />
| Accepted || Bool || Whether the action was accepted.<br />
|}<br />
<br />
==== Update Sign ====<br />
<br />
This message is sent from the server to the client whenever a sign is discovered or created. This message is NOT sent when a sign is destroyed or unloaded.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="7" | 0x33<br />
| X || Int || Block X Coordinate<br />
|-<br />
| Y || Short || Block Y Coordinate<br />
|-<br />
| Z || Int || Block Z Coordinate<br />
|-<br />
| Line 1 || String || First line of text in the sign<br />
|-<br />
| Line 2 || String || Second line of text in the sign<br />
|-<br />
| Line 3 || String || Third line of text in the sign<br />
|-<br />
| Line 4 || String || Fourth line of text in the sign<br />
|}<br />
<br />
==== Maps ====<br />
<br />
If the first byte of the array is 0, the next two bytes are X start and Y start and the rest of the bytes are the colors in that column.<br />
<br />
If the first byte of the array is 1, the rest of the bytes are in groups of three: (data, x, y). The lower half of the data is the type (always 0 under vanilla) and the upper half is the direction.<br />
<br />
If the first byte of the array is 2, the second byte is the map scale.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x34<br />
| Item Damage || VarInt || The damage value of the map being modified<br />
|-<br />
| Length || Short || Length of following byte array<br />
|-<br />
| Data || Byte Array || Array data<br />
|}<br />
<br />
==== Update Block Entity ====<br />
<br />
Essentially a block update on a block entity.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x35<br />
| X || Int ||<br />
|-<br />
| Y || Short ||<br />
|-<br />
| Z || Int ||<br />
|-<br />
| Action || Unsigned Byte || The type of update to perform<br />
|-<br />
| Data length || Short || Varies<br />
|-<br />
| NBT Data || Byte Array || Present if data length > 0. Compressed with [[wikipedia:Gzip|gzip]]. Varies<br />
|}<br />
<br />
'''Actions'''<br />
<br />
* '''1''': Set mob displayed inside a mob spawner. Custom 1 contains the [[Entities#Mobs|mob type]]<br />
<br />
==== Sign Editor Open ====<br />
<br />
Sent on placement of sign.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x36<br />
| X || Int || X in block coordinates<br />
|-<br />
| Y || Int || Y in block coordinates<br />
|-<br />
| Z || Int || Z in block coordinates<br />
|}<br />
<br />
==== Statistics ====<br />
{| class="wikitable"<br />
! Packet ID<br />
! colspan="2" | Field Name<br />
! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x37<br />
| colspan="2" | Count || VarInt || Number of entrys<br />
|-<br />
| rowspan=2 | Entry <br />
| Statistic's name || String || https://gist.github.com/thinkofdeath/a1842c21a0cf2e1fb5e0<br />
|-<br />
| Value || VarInt || The amount to set it too<br />
|}<br />
<br />
==== Player List Item ====<br />
<br />
Sent by the notchian server to update the user list (<tab> in the client).<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x38<br />
| Player name || String || Supports chat colouring, limited to 16 characters.<br />
|-<br />
| Online || Bool || The client will remove the user from the list if false.<br />
|-<br />
| Ping || Short || Ping, presumably in ms.<br />
|}<br />
<br />
==== Player Abilities ====<br />
<br />
The latter 2 floats are used to indicate the walking and flying speeds respectively, while the first byte is used to determine the value of 4 booleans.<br />
<br />
The flags are whether damage is disabled (god mode, 8, bit 3), whether the player can fly (4, bit 2), whether the player is flying (2, bit 1), and whether the player is in creative mode (1, bit 0).<br />
<br />
To get the values of these booleans, simply AND (&) the byte with 1,2,4 and 8 respectively, to get the 0 or 1 bitwise value. To set them OR (|) them with their repspective masks.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x39<br />
| Flags || Byte ||<br />
|-<br />
| Flying speed || Float|| previous integer value divided by 250<br />
|-<br />
| Walking speed || Float || previous integer value divided by 250<br />
|}<br />
<br />
==== Tab-Complete ====<br />
<br />
The server responds with a list of auto-completions of the last word sent to it. In the case of regular chat, this is a player username. Command names and parameters are also supported.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2| 0x3A <br />
| Count || VarInt || Number of following strings<br />
|-<br />
| Match || String || Possible Tab-Complete<br />
|}<br />
<br />
==== Scoreboard Objective ====<br />
<br />
This is sent to the client when it should create a new scoreboard or remove one.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x3B<br />
| Objective name || String || An unique name for the objective<br />
|-<br />
| Objective value || String || The text to be displayed for the score.<br />
|-<br />
| Create/Remove || Byte || 0 to create the scoreboard. 1 to remove the scoreboard. 2 to update the display text. <br />
|}<br />
<br />
==== Update Score ====<br />
<br />
This is sent to the client when it should update a scoreboard item.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x3C<br />
| Item Name || String || An unique name to be displayed in the list.<br />
|-<br />
| Update/Remove || Byte || 0 to create/update an item. 1 to remove an item.<br />
|-<br />
| Score Name || String || The unique name for the scoreboard to be updated. Only sent when Update/Remove does not equal 1.<br />
|-<br />
| Value || Int || The score to be displayed next to the entry. Only sent when Update/Remove does not equal 1.<br />
|}<br />
<br />
==== Display Scoreboard ====<br />
<br />
This is sent to the client when it should display a scoreboard.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x3D<br />
| Position || Byte || The position of the scoreboard. 0 = list, 1 = sidebar, 2 = belowName.<br />
|-<br />
| Score Name || String || The unique name for the scoreboard to be displayed.<br />
|}<br />
<br />
==== Teams ====<br />
<br />
Creates and updates teams.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="8" | 0x3E<br />
| Team Name || String || A unique name for the team. (Shared with scoreboard).<br />
|-<br />
| Mode || Byte || If 0 then the team is created. <br />
If 1 then the team is removed. <br />
<br />
If 2 the team team information is updated. <br />
<br />
If 3 then new players are added to the team. <br />
<br />
If 4 then players are removed from the team.<br />
|-<br />
| Team Display Name || String || Only if Mode = 0 or 2. <br />
|-<br />
| Team Prefix || String || Only if Mode = 0 or 2. Displayed before the players' name that are part of this team. <br />
|-<br />
| Team Suffix || String || Only if Mode = 0 or 2. Displayed after the players' name that are part of this team. <br />
|-<br />
| Friendly fire || Byte || Only if Mode = 0 or 2; 0 for off, 1 for on, 3 for seeing friendly invisibles<br />
|-<br />
| Player count || Short || Only if Mode = 0 or 3 or 4. Number of players in the array<br />
|-<br />
| Players || Array of strings || Only if Mode = 0 or 3 or 4. Players to be added/remove from the team.<br />
|}<br />
<br />
==== Plugin Message ====<br />
<br />
Mods and plugins can use this to send their data. Minecraft itself uses a number of [[plugin channel]]s. These internal channels are prefixed with <code>MC|</code>.<br />
<br />
More documentation on this: http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x3F<br />
| Channel || String || Name of the "channel" used to send the data.<br />
|-<br />
| Length || Short || Length of the following byte array<br />
|-<br />
| Data || Byte Array || Any data.<br />
|}<br />
<br />
==== Disconnect ====<br />
<br />
Sent by the server before it disconnects a client. The server assumes that the sender has already closed the connection by the time the packet arrives.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| 0x40<br />
| Reason || String || Displayed to the client when the connection terminates<br />
|}<br />
<br />
=== Serverbound ===<br />
<br />
==== Keep Alive ====<br />
<br />
The server will frequently send out a keep-alive, each containing a random ID. The client must respond with the same packet.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00<br />
| Keep Alive ID || Int ||<br />
|}<br />
<br />
==== Chat Message ==== <br />
<br />
The default server will check the message to see if it begins with a '/'. If it doesn't, the username of the sender is prepended and sent to all other clients (including the original sender). If it does, the server assumes it to be a command and attempts to process it. A message longer than 100 characters will cause the server to kick the client. This change was initially done by allowing the client to not slice the message up to 119 (the previous limit), without changes to the server. For this reason, the vanilla server kept the code to cut messages at 119, but this isn't a protocol limitation and can be ignored.<br />
<br />
For more information, see [[Chat]].<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x01<br />
| Message || String || <br />
|}<br />
<br />
==== Use Entity ====<br />
<br />
This packet is sent from the client to the server when the client attacks or right-clicks another entity (a player, minecart, etc).<br />
<br />
A Notchian server only accepts this packet if the entity being attacked/used is visible without obstruction and within a 4-unit radius of the player's position.<br />
<br />
Note that middle-click in creative mode is interpreted by the client and sent as a Creative Inventory Action packet instead.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x02<br />
| Target || Int ||<br />
|-<br />
| Mouse || Byte || 0 = Left-click, 1 = Right-click<br />
|}<br />
<br />
==== Player ====<br />
<br />
This packet is used to indicate whether the player is on ground (walking/swimming), or airborne (jumping/falling).<br />
<br />
When dropping from sufficient height, fall damage is applied when this state goes from False to True. The amount of damage applied is based on the point where it last changed from True to False. Note that there are several movement related packets containing this state.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x03<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Player Position ==== <br />
<br />
Updates the players XYZ position on the server. <br />
If <code>Stance - Y</code> is less than <code>0.1</code> or greater than <code>1.65</code>, the stance is illegal and the client will be kicked with the message “Illegal Stance”.<br />
If the distance between the last known position of the player on the server and the new position set by this packet is greater than 100 units will result in the client being kicked for "You moved too quickly :( (Hacking?)"<br />
Also if the fixed-point number of X or Z is set greater than <code>3.2E7D</code> the client will be kicked for "Illegal position" <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5| 0x04<br />
| X || Double || Absolute position<br />
|-<br />
| Y || Double || Absolute position<br />
|-<br />
| Stance || Double || Used to modify the players bounding box when going up stairs, crouching, etc…<br />
|-<br />
| Z || Double || Absolute position<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Player Look ==== <br />
<br />
[[File:Minecraft-trig-yaw.png|thumb|The unit circle for yaw]]<br />
<br />
Updates the direction the player is looking in.<br />
<br />
Yaw is measured in degrees, and does not follow classical trigonometry rules. The unit circle of yaw on the xz-plane starts at (0, 1) and turns backwards towards (-1, 0), or in other words, it turns clockwise instead of counterclockwise. Additionally, yaw is not clamped to between 0 and 360 degrees; any number is valid, including negative numbers and numbers greater than 360.<br />
<br />
Pitch is measured in degrees, where 0 is looking straight ahead, -90 is looking straight up, and 90 is looking straight down.<br />
<br />
You can get a unit vector from a given yaw/pitch via:<br />
x = -cos(pitch) * sin(yaw)<br />
y = -sin(pitch)<br />
z = cos(pitch) * cos(yaw)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=3| 0x05<br />
| Yaw || Float || Absolute rotation on the X Axis, in degrees<br />
|-<br />
| Pitch || Float || Absolute rotation on the Y Axis, in degrees<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Player Position And Look ==== <br />
<br />
A combination of Player Look and Player position. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=7| 0x06<br />
| X || Double || Absolute position<br />
|-<br />
| Y || Double || Absolute position<br />
|-<br />
| Stance || Double || Used to modify the players bounding box when going up stairs, crouching, etc…<br />
|-<br />
| Z || Double || Absolute position<br />
|-<br />
| Yaw || Float || Absolute rotation on the X Axis, in degrees<br />
|-<br />
| Pitch || Float || Absolute rotation on the Y Axis, in degrees<br />
|-<br />
| On Ground || Bool || True if the client is on the ground, False otherwise<br />
|}<br />
<br />
==== Player Digging ====<br />
<br />
Sent when the player mines a block. A Notchian server only accepts digging packets with coordinates within a 6-unit radius of the player's position.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="5" | 0x07<br />
| Status || Byte || The action the player is taking against the block (see below)<br />
|-<br />
| X || Int || Block position<br />
|-<br />
| Y || Unsigned Byte || Block position<br />
|-<br />
| Z || Int || Block position<br />
|-<br />
| Face || Byte || The face being hit (see below)<br />
|}<br />
<br />
Status can (currently) be one of six values:<br />
<br />
{| class="wikitable"<br />
! Meaning !! Value<br />
|-<br />
| Started digging || <code>0</code><br />
|-<br />
| Cancelled digging || <code>1</code><br />
|-<br />
| Finished digging || <code>2</code><br />
|-<br />
| Drop item stack || <code>3</code><br />
|-<br />
| Drop item || <code>4</code><br />
|-<br />
| Shoot arrow / finish eating || <code>5</code><br />
|}<br />
<br />
Notchian clients send a 0 (started digging) when they start digging and a 2 (finished digging) once they think they are finished. If digging is aborted, the client simply send a 1 (Cancel digging).<br />
<br />
Status code 4 (drop item) is a special case. In-game, when you use the Drop Item command (keypress 'q'), a dig packet with a status of 4, and all other values set to 0, is sent from client to server. Status code 3 is similar, but drops the entire stack.<br />
<br />
Status code 5 (shoot arrow / finish eating) is also a special case. The x, y and z fields are all set to 0 like above, with the exception of the face field, which is set to 255.<br />
<br />
The face can be one of six values, representing the face being hit:<br />
<br />
{| class="wikitable"<br />
|-<br />
| Value || 0 || 1 || 2 || 3 || 4 || 5<br />
|-<br />
| Offset || -Y || +Y || -Z || +Z || -X || +X<br />
|}<br />
<br />
In 1.7.3, when a player opens a door with left click the server receives Packet 0xE+start digging and opens the door.<br />
<br />
==== Player Block Placement ====<br />
{| class="wikitable"<br />
|-<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="8" | 0x08<br />
| X || Int || Block position<br />
|-<br />
| Y || Unsigned Byte || Block position<br />
|-<br />
| Z || Int || Block position<br />
|-<br />
| Direction || Byte || The offset to use for block/item placement (see below)<br />
|-<br />
| Held item || [[Slot_Data|Slot]] ||<br />
|-<br />
| Cursor position X || Byte || The position of the crosshair on the block<br />
|-<br />
| Cursor position Y || Byte ||<br />
|-<br />
| Cursor position Z || Byte ||<br />
|}<br />
In normal operation (ie placing a block), this packet is sent once, with the values set normally.<br />
<br />
This packet has a special case where X, Y, Z, and Direction are all -1. (Note that Y is unsigned so set to 255.) This special packet indicates that the currently held item for the player should have its state updated such as eating food, shooting bows, using buckets, etc.<br />
<br />
In a Notchian Beta client, the block or item ID corresponds to whatever the client is currently holding, and the client sends one of these packets any time a right-click is issued on a surface, so no assumptions can be made about the safety of the ID. However, with the implementation of server-side inventory, a Notchian server seems to ignore the item ID, instead operating on server-side inventory information and holding selection. The client has been observed (1.2.5 and 1.3.2) to send both real item IDs and -1 in a single session.<br />
<br />
Special note on using buckets: When using buckets, the Notchian client might send two packets: first a normal and then a special case. The first normal packet is sent when you're looking at a block (e.g. the water you want to scoop up). This normal packet does not appear to do anything with a Notchian server. The second, special case packet appears to perform the action - based on current position/orientation and with a distance check - it appears that buckets can only be used within a radius of 6 units.<br />
<br />
==== Held Item Change ==== <br />
<br />
Sent when the player changes the slot selection<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x09<br />
| Slot || Short || The slot which the player has selected (0-8)<br />
|}<br />
<br />
==== Animation ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x0A<br />
| Entity ID || Int || Player ID<br />
|-<br />
| Animation || Byte || Animation ID<br />
|}<br />
<br />
<br />
Animation can be one of the following values:<br />
<br />
{| class="wikitable"<br />
! ID !! Animation<br />
|-<br />
| 0 || No animation<br />
|-<br />
| 1 || Swing arm<br />
|-<br />
| 2 || Damage animation<br />
|-<br />
| 3 || Leave bed<br />
|-<br />
| 5 || Eat food<br />
|-<br />
| 6 || Critical effect<br />
|-<br />
| 7 || Magic critical effect<br />
|-<br />
| 102 || (unknown)<br />
|-<br />
| 104 || Crouch<br />
|-<br />
| 105 || Uncrouch<br />
|}<br />
<br />
==== Entity Action ====<br />
<br />
Sent at least when crouching, leaving a bed, or sprinting.<br />
To send action animation to client use 0x28.<br />
The client will send this with Action ID = 3 when "Leave Bed" is clicked.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x0B<br />
| Entity ID || Int || Player ID<br />
|-<br />
| Action ID || Byte || The ID of the action, see below.<br />
|-<br />
| Jump Boost || Int || Horse jump boost. Ranged from 0 -> 100.<br />
|}<br />
<br />
Action ID can be one of the following values:<br />
<br />
{| class="wikitable"<br />
! ID !! Action<br />
|-<br />
| 1 || Crouch<br />
|-<br />
| 2 || Uncrouch<br />
|-<br />
| 3 || Leave bed<br />
|-<br />
| 4 || Start sprinting<br />
|-<br />
| 5 || Stop sprinting<br />
|}<br />
<br />
==== Steer Vehicle ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="4" | 0x0C<br />
| Sideways || Float || Positive to the left of the player<br />
|-<br />
| Forward || Float || Positive forward<br />
|-<br />
| Jump || Bool ||<br />
|-<br />
| Unmount || Bool || True when leaving the vehicle<br />
|}<br />
<br />
==== Close Window ====<br />
<br />
This packet is sent by the client when closing a window. <br />
<br />
Note, notchian clients send a close window message with window id 0 to close their inventory even though there is never an Open Window message for inventory. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| 0x0D<br />
| Window id || byte || This is the id of the window that was closed. 0 for inventory.<br />
|}<br />
<br />
<br />
==== Click Window ====<br />
<br />
This packet is sent by the player when it clicks on a slot in a window.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x0E<br />
| Window ID || Byte || The id of the window which was clicked. 0 for player inventory.<br />
|-<br />
| Slot || Short || The clicked slot. See below.<br />
|-<br />
| Button || Byte || The button used in the click. See below.<br />
|-<br />
| Action number || Short || A unique number for the action, used for transaction handling (See the Transaction packet).<br />
|-<br />
| Mode || Byte || Inventory operation mode. See below.<br />
|-<br />
| Clicked item || [[Slot_Data|Slot]] ||<br />
|}<br />
<br />
See [[Inventory#Windows|inventory windows]] for further information about how slots are indexed.<br />
<br />
When right-clicking on a stack of items, half the stack will be picked up and half left in the slot. If the stack is an odd number, the half left in the slot will be smaller of the amounts.<br />
<br />
The Action number is actually a counter, starting at 1. This number is used by the server as a transaction ID to send back a [[#0x6A|Transaction packet]].<br />
<br />
The distinct type of click performed by the client is determined by the combination of the "Mode" and "Button" fields.<br />
{| class="wikitable"<br />
! Mode !! Button !! Slot !! Trigger<br />
|-<br />
! rowspan="2" | 0<br />
| 0 || Normal || Left mouse click<br />
|-<br />
| 1 || Normal || Right mouse click<br />
|-<br />
! rowspan="2" | 1<br />
| 0 || Normal || Shift + left mouse click<br />
|-<br />
| 1 || Normal || Shift + right mouse click ''(Identical behavior)''<br />
|-<br />
! rowspan="5" | 2<br />
| 0 || Normal || Number key 1<br />
|-<br />
| 1 || Normal || Number key 2<br />
|-<br />
| 2 || Normal || Number key 3<br />
|-<br />
| ...<br />
| ...<br />
| ...<br />
|-<br />
| 8 || Normal || Number key 9<br />
|-<br />
! rowspan="1" | 3<br />
| 2 || Normal || Middle click<br />
|-<br />
! rowspan="4" | 4<br />
| 0 || Normal || Drop key (Q)<br />
|-<br />
| 1 || Normal || Ctrl + Drop key (Ctrl-Q)<br />
|-<br />
| 0 || -999 || Left click outside inventory holding nothing ''(No-op)''<br />
|-<br />
| 1 || -999 || Right click outside inventory holding nothing ''(No-op)''<br />
|-<br />
! rowspan="6" | 5<br />
| 0 || -999 || Starting left mouse drag ''(Or middle mouse)''<br />
|-<br />
| 4 || -999 || Starting right mouse drag<br />
|-<br />
| 1 || Normal || Add slot for left-mouse drag<br />
|-<br />
| 5 || Normal || Add slot for right-mouse drag<br />
|-<br />
| 2 || -999 || Ending left mouse drag<br />
|-<br />
| 6 || -999 || Ending right mouse drag<br />
|-<br />
! 6 <br />
| 0 || Normal || Double click<br />
|}<br />
<br />
Starting from version 1.5, "painting mode" is available for use in inventory windows. It is done by picking up stack of something (more than 1 items), then holding mouse button (left, right or middle) and dragging holded stack over empty (or same type in case of right button ) slots. In that case client sends the following to server after mouse button release (omitting first pickup packet which is sent as usual):<br />
<br />
# packet with mode 5, slot -999 , button (0 for left | 4 for right);<br />
# packet for every slot painted on, mode is still 5, button (1 | 5);<br />
# packet with mode 5, slot -999, button (2 | 6);<br />
<br />
If any of the painting packets other than the "progress" ones are sent out of order (for example, a start, some slots, then another start; or a left-click in the middle) the painting status will be reset.<br />
<br />
==== Confirm Transaction ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x0F<br />
| Window ID || Byte || The id of the window that the action occurred in.<br />
|-<br />
| Action number || Short || Every action that is to be accepted has a unique number. This field corresponds to that number.<br />
|-<br />
| Accepted || Bool || Whether the action was accepted.<br />
|}<br />
<br />
==== Creative Inventory Action ====<br />
<br />
While the user is in the standard inventory (i.e., not a crafting bench) on a creative-mode server then the server will send this packet:<br />
<br />
* If an item is dropped into the quick bar<br />
* If an item is picked up from the quick bar (item id is -1)<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x10<br />
| Slot || Short || Inventory slot<br />
|-<br />
| Clicked item || [[Slot_Data|Slot]] ||<br />
|}<br />
<br />
==== Enchant Item ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="2" | 0x11<br />
| Window ID || Byte || The ID sent by [[#0x64|Open Window]]<br />
|-<br />
| Enchantment || Byte || The position of the enchantment on the enchantment table window, starting with 0 as the topmost one.<br />
|}<br />
<br />
==== Update Sign ====<br />
<br />
This message is sent from the client to the server when the "Done" button is pushed after placing a sign. <br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="7" | 0x12<br />
| X || Int || Block X Coordinate<br />
|-<br />
| Y || Short || Block Y Coordinate<br />
|-<br />
| Z || Int || Block Z Coordinate<br />
|-<br />
| Line 1 || String || First line of text in the sign<br />
|-<br />
| Line 2 || String || Second line of text in the sign<br />
|-<br />
| Line 3 || String || Third line of text in the sign<br />
|-<br />
| Line 4 || String || Fourth line of text in the sign<br />
|}<br />
<br />
==== Player Abilities ====<br />
<br />
The latter 2 bytes are used to indicate the walking and flying speeds respectively, while the first byte is used to determine the value of 4 booleans.<br />
<br />
The flags are whether damage is disabled (god mode, 8, bit 3), whether the player can fly (4, bit 2), whether the player is flying (2, bit 1), and whether the player is in creative mode (1, bit 0).<br />
<br />
To get the values of these booleans, simply AND (&) the byte with 1,2,4 and 8 respectively, to get the 0 or 1 bitwise value. To set them OR (|) them with their repspective masks.<br />
The vanilla client sends this packet when the player starts/stops flying with the second parameter changed accordingly. All other parameters are ignored by the vanilla server.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x13<br />
| Flags || Byte ||<br />
|-<br />
| Flying speed || Float|| previous integer value divided by 250<br />
|-<br />
| Walking speed || Float || previous integer value divided by 250<br />
|}<br />
<br />
==== Tab-Complete ====<br />
<br />
Sent when the user presses [tab] while writing text. The payload contains all text behind the cursor.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| 0x14 <br />
| Text || String ||<br />
|}<br />
<br />
==== Client Settings ====<br />
<br />
Sent when the player connects, or when settings are changed.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="6" | 0x15<br />
| Locale || String || en_GB<br />
|-<br />
| View distance || Byte || 0-3 for 'far', 'normal', 'short', 'tiny'.<br />
|-<br />
| Chat flags || Byte || Chat settings. See notes below.<br />
|-<br />
| Unused || Bool || Only observed as true<br />
|-<br />
| Difficulty || Byte || Client-side difficulty from options.txt<br />
|-<br />
| Show Cape || Bool || Client-side "show cape" option<br />
|}<br />
<br />
Chat flags has several values packed into one byte.<br />
<br />
'''Chat Enabled:''' Bits 0-1. 00: Enabled. 01: Commands only. 10: Hidden.<br />
<br />
'''Colors Enabled:''' Bit 3. 0: Disabled. 1: Enabled.<br />
<br />
==== Client Status ====<br />
<br />
Sent when the client is ready to complete login and when the client is ready to respawn after death.<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x16<br />
| Action ID || Byte || See below<br />
|}<br />
<br />
Action ID values:<br />
{| class="wikitable"<br />
|-<br />
! Action ID !! Name<br />
|-<br />
| 0 || Perform respawn<br />
|-<br />
| 1 || Request stats<br />
|-<br />
| 2 || Open inventory achievement<br />
|}<br />
<br />
==== Plugin Message ====<br />
<br />
Mods and plugins can use this to send their data. Minecraft itself uses a number of [[plugin channel]]s. These internal channels are prefixed with <code>MC|</code>.<br />
<br />
More documentation on this: http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/<br />
<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan="3" | 0x17<br />
| Channel || String || Name of the "channel" used to send the data.<br />
|-<br />
| Length || Short || Length of the following byte array<br />
|-<br />
| Data || Byte Array || Any data.<br />
|}<br />
<br />
== Status ==<br />
The status ping works as follows. <br />
C->S : Handshake State=1<br />
C->S : Request<br />
S->C : Response<br />
C->S : Ping<br />
S->C : Ping<br />
<br />
=== Clientbound ===<br />
<br />
==== Response ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00 <br />
| JSON Response || String || https://gist.github.com/thinkofdeath/6927216<br />
|}<br />
<br />
<br />
==== Ping ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x01 <br />
| Time || Long || Should be the same as sent by the client<br />
|}<br />
<br />
=== Serverbound ===<br />
<br />
==== Request ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00 || || ||<br />
|}<br />
<br />
<br />
==== Ping ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x01 <br />
| Time || Long ||<br />
|}<br />
<br />
== Login ==<br />
<br />
The login process is as follows:<br />
C->S : Handshake State=2<br />
C->S : Login Start<br />
S->C : Encryption Key Request<br />
(Client Auth)<br />
C->S : Encryption Key Response<br />
(Server Auth, Both enable encryption)<br />
S->C : Login Success<br />
<br />
For unauthenticated and* localhost connections there is no encryption.<br />
In that case Login Start is directly followed by Login Success.<br />
<br />
<nowiki>*</nowiki> It could be that only one of the two conditions is enough for an unencrypted connection.<br />
<br />
=== Clientbound ===<br />
<br />
==== Disconnect ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00<br />
| JSON Data || String ||<br />
|}<br />
<br />
==== Encryption Request ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=5 | 0x01 <br />
| Server ID || String ||<br />
|-<br />
| Length || Short || length of public key<br />
|-<br />
| Public Key || Byte array || <br />
|-<br />
| Length || Short || length of verify token<br />
|-<br />
| Verify Token || Byte array || <br />
|- <br />
|}<br />
<br />
==== Login Success ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=2 | 0x02<br />
| UUID || String ||<br />
|-<br />
| Username || String ||<br />
|}<br />
<br />
=== Serverbound ===<br />
<br />
==== Login Start ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=1 | 0x00<br />
| Name || String || <br />
|}<br />
<br />
==== Encryption Response ====<br />
{| class="wikitable"<br />
! Packet ID !! Field Name !! Field Type !! Notes<br />
|-<br />
| rowspan=4 | 0x01 <br />
| Length || Short || length of public key<br />
|-<br />
| Public Key || Byte array || <br />
|-<br />
| Length || Short || length of verify token<br />
|-<br />
| Verify Token || Byte array ||<br />
|- <br />
|}<br />
<br />
== See Also ==<br />
* [[Data Types]]<br />
* [[Protocol History]]<br />
* [[Units of Measurement]]<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Data_types&diff=4618Data types2013-08-28T00:15:24Z<p>Drainedsoul: Add 128-bit integer</p>
<hr />
<div>All data sent over the network is [http://en.wikipedia.org/wiki/Endianness#Big-endian big-endian], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<br />
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html DataInputStream] and [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataOutputStream.html DataOutputStream].<br />
<br />
{| class="wikitable"<br />
|- class="row0"<br />
| class="col0" |<br />
! class="col1" | Size<br />
! class="col2" | Range<br />
! class="col3" | Notes<br />
|- class="row1"<br />
! class="col0 centeralign" | bool<br />
| class="col1 centeralign" | 1<br />
| class="col2" | 0 or 1<br />
| class="col3" | Value can be either true (0x01) or false (0x00)<br />
|- class="row2"<br />
! class="col0 centeralign" | byte<br />
| class="col1 centeralign" | 1<br />
| class="col2" | -128 to 127<br />
| class="col3" | Signed, two's complement<br />
|- class="row3"<br />
! class="col0 centeralign" | short<br />
| class="col1 centeralign" | 2<br />
| class="col2" | -32768 to 32767<br />
| class="col3" | Signed, two's complement<br />
|- class="row4"<br />
! class="col0 centeralign" | int<br />
| class="col1 centeralign" | 4<br />
| class="col2" | -2147483648 to 2147483647<br />
| class="col3" | Signed, two's complement<br />
|- class="row5"<br />
! class="col0 centeralign" | long<br />
| class="col1 centeralign" | 8<br />
| class="col2" | -9223372036854775808 to 9223372036854775807<br />
| class="col3" | Signed, two's complement<br />
|- class="row8"<br />
! class="col0 centeralign" | 128-bit integer<br />
| class="col1 centeralign" | 16<br />
| class="col2" | 0 to 340282366920938463463374607431768211455<br />
| class="col3" | Unsigned, two's complement<br />
<br />
Used in [http://wiki.vg/Protocol#Entity_Properties_.280x2C.29 0x2C] to transmit UUIDs.<br />
<br />
The vanilla Minecraft server internally sends this as two longs.<br />
|- class="row7"<br />
! class="col0 centeralign" | float<br />
| class="col1 centeralign" | 4<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Single-precision 32-bit IEEE 754 floating point<br />
|- class="row8"<br />
! class="col0 centeralign" | double<br />
| class="col1 centeralign" | 8<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Double-precision 64-bit IEEE 754 floating point<br />
|- class="row9"<br />
! class="col0 centeralign" | string<br />
| class="col1 centeralign" | ≥ 2 <br />≤ 240<br />
| class="col2" | N/A<br />
| class="col3" | [http://en.wikipedia.org/wiki/UTF-16 UTF-16] big-endian string prefixed by a short containing the length of the string in code units.<br />
<br />
UTF-16 is a variable-length encoding, which means that a single Unicode code point (what most programmers think of as a "character") may be encoded by a variable number of code units.<br />
<br />
UTF-16 encodes code points as either one or two 16 bit code units.<br />
<br />
Characters in the Basic Multilingual Plane (U+0000 through U+FFFF inclusive) are encoded as one 16 bit code unit.<br />
<br />
Characters in the other Unicode planes (U+10000 through U+10FFFF inclusive) are encoded as two 16 bit code units (a high/low "surrogate pair").<br />
<br />
Therefore, the length in bytes of a string may be obtained by multiplying the number of code units by two, and the opposite operation may be performed by dividing by two.<br />
<br />
However, since UTF-16 is variable-length, the number of code units is totally unrelated to the number of code points (i.e. "characters"), and you will actually have to decode the string to obtain this information.<br />
<br />
It was historically believed that the Minecraft protocol used the fixed-width encoding UCS-2, however this has since been proven to be incorrect.<br />
|- class="row9"<br />
! class="col0 centeralign" | metadata<br />
| class="col1 centeralign" | Varies<br />
| class="col2" | See [[Entities#Entity_Metadata_Format|this]]<br />
| class="Col3" | <br />
|}<br />
<br />
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double. The conversion from double to absolute integer is like so:<br />
<br />
abs_int = (int)double * 32;<br />
<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Server_List_Ping&diff=4522Server List Ping2013-08-26T19:51:10Z<p>Drainedsoul: Minecraft actually uses UTF-16</p>
<hr />
<div>Minecraft supports querying the MOTD, player count, max players and server version via the usual port. Unlike [[Query]], the server list ping interface is always enabled.<br />
<br />
== 1.6 ==<br />
<br />
=== Client -> Server ===<br />
<br />
The client initiates a TCP connection to the minecraft server on the standard port. Instead of doing auth and logging in (as detailed in [[Protocol Encryption]]), it sends the following data, expressed in hexadecimal:<br />
<br />
# <code>FE</code> - packet identifier for a [[Protocol#0xFE|server list ping]]<br />
# <code>01</code> - server list ping's payload (always 1)<br />
# <code>FA</code> - packet identifier for a [[Protocol#0xFA|plugin message]]<br />
# <code>00 0B</code> - length of following string, in characters, as a short (always 11)<br />
# <code>00 4D 00 43 00 7C 00 50 00 69 00 6E 00 67 00 48 00 6F 00 73 00 74</code> - the string "MC|PingHost" encoded as a [http://en.wikipedia.org/wiki/UTF-16 UTF-16BE] string<br />
# <code>XX XX</code> - length of the rest of the data, as a short. Compute as <code>7 + 2*len(hostname)</code><br />
# <code>XX</code> - protocol version - currently 74 (decimal)<br />
# <code>XX XX</code> - length of following string, in characters, as a short<br />
# <code>...</code> - hostname the client is connecting to, encoded the same way as "MC|PingHost"<br />
# <code>XX XX XX XX</code> - port the client is connecting to, as an int.<br />
<br />
All [[Data_Types|data types]] are big-endian.<br />
<br />
Packet dump:<br />
<br />
0000000: fe01 fa00 0b00 4d00 4300 7c00 5000 6900 ......M.C.|.P.i.<br />
0000010: 6e00 6700 4800 6f00 7300 7400 1949 0009 n.g.H.o.s.t..I..<br />
0000020: 006c 006f 0063 0061 006c 0068 006f 0073 .l.o.c.a.l.h.o.s<br />
0000030: 0074 0000 63dd .t..c.<br />
<br />
=== Server -> Client ===<br />
<br />
The server responds with a [[Protocol#Disconnect.2FKick_.280xFF.29|0xFF kick]] packet. The packet begins with a single byte identifier <code>ff</code>, then a two-byte big endian short giving the length of the proceeding string in characters. You can actually ignore the length because the server closes the connection after the response is sent.<br />
<br />
After the first 3 bytes, the packet is a UTF-16BE string. It begins with two characters: <code>§1</code>, followed by a null character. On the wire these look like <code>00 a7 00 31 00 00</code>.<br />
<br />
The remainder is null character (that is <code>00 00</code>) delimited fields:<br />
<br />
# Protocol version (e.g. <code>47</code>)<br />
# Minecraft server version (e.g. <code>1.4.2</code>)<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 2300 a700 3100 0000 3400 3700 0000 ....§.1...4.7...<br />
0000010: 3100 2e00 3400 2e00 3200 0000 4100 2000 1...4...2...A. .<br />
0000020: 4d00 6900 6e00 6500 6300 7200 6100 6600 M.i.n.e.c.r.a.f.<br />
0000030: 7400 2000 5300 6500 7200 7600 6500 7200 t. .S.e.r.v.e.r.<br />
0000040: 0000 3000 0000 3200 30 ..0...2.0<br />
<br />
== 1.4 - 1.5 ==<br />
<br />
Prior to the Minecraft 1.6, the client -> server operation is much simpler, and only sends <code>FE 01</code>, with none of the following data beginning <code>FA ...</code><br />
<br />
== Beta 1.8 - 1.3 ==<br />
<br />
Prior to Minecraft 1.4, the client only sends <code>FE</code>. <br />
<br />
Additionally, the response from the server only contains 3 fields delimited by <code>§</code>:<br />
<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 1700 4100 2000 4d00 6900 6e00 6500 ....A. .M.i.n.e.<br />
0000010: 6300 7200 6100 6600 7400 2000 5300 6500 c.r.a.f.t. .S.e.<br />
0000020: 7200 7600 6500 7200 a700 3000 a700 3100 r.v.e.r.§.0.§.1.<br />
0000030: 30 0<br />
<br />
<br />
== Sample code ==<br />
<br />
* [https://gist.github.com/1209061 Python]<br />
* [https://gist.github.com/6281388 Ruby]<br />
* [https://gist.github.com/5795159 PHP]<br />
* [https://gist.github.com/4574114 Java]<br />
* [https://gist.github.com/6223787 C#]</div>Drainedsoulhttps://wiki.vg/index.php?title=Data_types&diff=4521Data types2013-08-26T19:49:34Z<p>Drainedsoul: Fix typo</p>
<hr />
<div>All data sent over the network is [http://en.wikipedia.org/wiki/Endianness#Big-endian big-endian], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<br />
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html DataInputStream] and [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataOutputStream.html DataOutputStream].<br />
<br />
{| class="wikitable"<br />
|- class="row0"<br />
| class="col0" |<br />
! class="col1" | Size<br />
! class="col2" | Range<br />
! class="col3" | Notes<br />
|- class="row1"<br />
! class="col0 centeralign" | bool<br />
| class="col1 centeralign" | 1<br />
| class="col2" | 0 or 1<br />
| class="col3" | Value can be either true (0x01) or false (0x00)<br />
|- class="row2"<br />
! class="col0 centeralign" | byte<br />
| class="col1 centeralign" | 1<br />
| class="col2" | -128 to 127<br />
| class="col3" | Signed, two's complement<br />
|- class="row3"<br />
! class="col0 centeralign" | short<br />
| class="col1 centeralign" | 2<br />
| class="col2" | -32768 to 32767<br />
| class="col3" | Signed, two's complement<br />
|- class="row4"<br />
! class="col0 centeralign" | int<br />
| class="col1 centeralign" | 4<br />
| class="col2" | -2147483648 to 2147483647<br />
| class="col3" | Signed, two's complement<br />
|- class="row5"<br />
! class="col0 centeralign" | long<br />
| class="col1 centeralign" | 8<br />
| class="col2" | -9223372036854775808 to 9223372036854775807<br />
| class="col3" | Signed, two's complement<br />
|- class="row6"<br />
! class="col0 centeralign" | float<br />
| class="col1 centeralign" | 4<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Single-precision 32-bit IEEE 754 floating point<br />
|- class="row7"<br />
! class="col0 centeralign" | double<br />
| class="col1 centeralign" | 8<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Double-precision 64-bit IEEE 754 floating point<br />
|- class="row8"<br />
! class="col0 centeralign" | string<br />
| class="col1 centeralign" | ≥ 2 <br />≤ 240<br />
| class="col2" | N/A<br />
| class="col3" | [http://en.wikipedia.org/wiki/UTF-16 UTF-16] big-endian string prefixed by a short containing the length of the string in code units.<br />
<br />
UTF-16 is a variable-length encoding, which means that a single Unicode code point (what most programmers think of as a "character") may be encoded by a variable number of code units.<br />
<br />
UTF-16 encodes code points as either one or two 16 bit code units.<br />
<br />
Characters in the Basic Multilingual Plane (U+0000 through U+FFFF inclusive) are encoded as one 16 bit code unit.<br />
<br />
Characters in the other Unicode planes (U+10000 through U+10FFFF inclusive) are encoded as two 16 bit code units (a high/low "surrogate pair").<br />
<br />
Therefore, the length in bytes of a string may be obtained by multiplying the number of code units by two, and the opposite operation may be performed by dividing by two.<br />
<br />
However, since UTF-16 is variable-length, the number of code units is totally unrelated to the number of code points (i.e. "characters"), and you will actually have to decode the string to obtain this information.<br />
<br />
It was historically believed that the Minecraft protocol used the fixed-width encoding UCS-2, however this has since been proven to be incorrect.<br />
|- class="row9"<br />
! class="col0 centeralign" | metadata<br />
| class="col1 centeralign" | Varies<br />
| class="col2" | See [[Entities#Entity_Metadata_Format|this]]<br />
| class="Col3" | <br />
|}<br />
<br />
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double. The conversion from double to absolute integer is like so:<br />
<br />
abs_int = (int)double * 32;<br />
<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Data_types&diff=4520Data types2013-08-26T19:48:41Z<p>Drainedsoul: Elaborating on the vagaries of UTF-16</p>
<hr />
<div>All data sent over the network is [http://en.wikipedia.org/wiki/Endianness#Big-endian big-endian], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<br />
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html DataInputStream] and [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataOutputStream.html DataOutputStream].<br />
<br />
{| class="wikitable"<br />
|- class="row0"<br />
| class="col0" |<br />
! class="col1" | Size<br />
! class="col2" | Range<br />
! class="col3" | Notes<br />
|- class="row1"<br />
! class="col0 centeralign" | bool<br />
| class="col1 centeralign" | 1<br />
| class="col2" | 0 or 1<br />
| class="col3" | Value can be either true (0x01) or false (0x00)<br />
|- class="row2"<br />
! class="col0 centeralign" | byte<br />
| class="col1 centeralign" | 1<br />
| class="col2" | -128 to 127<br />
| class="col3" | Signed, two's complement<br />
|- class="row3"<br />
! class="col0 centeralign" | short<br />
| class="col1 centeralign" | 2<br />
| class="col2" | -32768 to 32767<br />
| class="col3" | Signed, two's complement<br />
|- class="row4"<br />
! class="col0 centeralign" | int<br />
| class="col1 centeralign" | 4<br />
| class="col2" | -2147483648 to 2147483647<br />
| class="col3" | Signed, two's complement<br />
|- class="row5"<br />
! class="col0 centeralign" | long<br />
| class="col1 centeralign" | 8<br />
| class="col2" | -9223372036854775808 to 9223372036854775807<br />
| class="col3" | Signed, two's complement<br />
|- class="row6"<br />
! class="col0 centeralign" | float<br />
| class="col1 centeralign" | 4<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Single-precision 32-bit IEEE 754 floating point<br />
|- class="row7"<br />
! class="col0 centeralign" | double<br />
| class="col1 centeralign" | 8<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Double-precision 64-bit IEEE 754 floating point<br />
|- class="row8"<br />
! class="col0 centeralign" | string<br />
| class="col1 centeralign" | ≥ 2 <br />≤ 240<br />
| class="col2" | N/A<br />
| class="col3" | [http://en.wikipedia.org/wiki/UTF-16 UTF-16] big-endian string prefixed by a short containing the length of the string in code units.<br />
<br />
UTF-16 is a variable-length encoding, which means that a single Unicode code point (what most programmers think of as a "character") may be encoded by a variable number of code units.<br />
<br />
UTF-16 encodes code points as either one or two 16 bit code units.<br />
<br />
Characters in the Basic Multilingual Plane (U+0000 through U+FFFF inclusive) are encoded as one 16 bit code unit.<br />
<br />
Characters in the other Unicode planes (U+10000 through U+10FFFF inclusive) are encoded as two 16 bit code units (a high/low "surrogate pair").<br />
<br />
Therefore, the length in bytes of a string may be obtained by multiplying the number of code points by two, and the opposite operation may be performed by dividing by two.<br />
<br />
However, since UTF-16 is variable-length, the number of code units is totally unrelated to the number of code points (i.e. "characters"), and you will actually have to decode the string to obtain this information.<br />
<br />
It was historically believed that the Minecraft protocol used the fixed-width encoding UCS-2, however this has since been proven to be incorrect.<br />
|- class="row9"<br />
! class="col0 centeralign" | metadata<br />
| class="col1 centeralign" | Varies<br />
| class="col2" | See [[Entities#Entity_Metadata_Format|this]]<br />
| class="Col3" | <br />
|}<br />
<br />
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double. The conversion from double to absolute integer is like so:<br />
<br />
abs_int = (int)double * 32;<br />
<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Server_List_Ping&diff=4519Server List Ping2013-08-26T19:19:57Z<p>Drainedsoul: Minecraft actually uses UTF-16</p>
<hr />
<div>Minecraft supports querying the MOTD, player count, max players and server version via the usual port. Unlike [[Query]], the server list ping interface is always enabled.<br />
<br />
== 1.6 ==<br />
<br />
=== Client -> Server ===<br />
<br />
The client initiates a TCP connection to the minecraft server on the standard port. Instead of doing auth and logging in (as detailed in [[Protocol Encryption]]), it sends the following data, expressed in hexadecimal:<br />
<br />
# <code>FE</code> - packet identifier for a [[Protocol#0xFE|server list ping]]<br />
# <code>01</code> - server list ping's payload (always 1)<br />
# <code>FA</code> - packet identifier for a [[Protocol#0xFA|plugin message]]<br />
# <code>00 0B</code> - length of following string, in characters, as a short (always 11)<br />
# <code>00 4D 00 43 00 7C 00 50 00 69 00 6E 00 67 00 48 00 6F 00 73 00 74</code> - the string "MC|PingHost" encoded as a big-endian [http://en.wikipedia.org/wiki/UTF-16/UCS-2 UCS-2] string<br />
# <code>XX XX</code> - length of the rest of the data, as a short. Compute as <code>7 + 2*len(hostname)</code><br />
# <code>XX</code> - protocol version - currently 74 (decimal)<br />
# <code>XX XX</code> - length of following string, in characters, as a short<br />
# <code>...</code> - hostname the client is connecting to, encoded the same way as "MC|PingHost"<br />
# <code>XX XX XX XX</code> - port the client is connecting to, as an int.<br />
<br />
All [[Data_Types|data types]] are big-endian.<br />
<br />
Packet dump:<br />
<br />
0000000: fe01 fa00 0b00 4d00 4300 7c00 5000 6900 ......M.C.|.P.i.<br />
0000010: 6e00 6700 4800 6f00 7300 7400 1949 0009 n.g.H.o.s.t..I..<br />
0000020: 006c 006f 0063 0061 006c 0068 006f 0073 .l.o.c.a.l.h.o.s<br />
0000030: 0074 0000 63dd .t..c.<br />
<br />
=== Server -> Client ===<br />
<br />
The server responds with a [[Protocol#Disconnect.2FKick_.280xFF.29|0xFF kick]] packet. The packet begins with a single byte identifier <code>ff</code>, then a two-byte big endian short giving the length of the proceeding string in characters. You can actually ignore the length because the server closes the connection after the response is sent.<br />
<br />
After the first 3 bytes, the packet is a UTF-16BE string. It begins with two characters: <code>§1</code>, followed by a null character. On the wire these look like <code>00 a7 00 31 00 00</code>.<br />
<br />
The remainder is null character (that is <code>00 00</code>) delimited fields:<br />
<br />
# Protocol version (e.g. <code>47</code>)<br />
# Minecraft server version (e.g. <code>1.4.2</code>)<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 2300 a700 3100 0000 3400 3700 0000 ....§.1...4.7...<br />
0000010: 3100 2e00 3400 2e00 3200 0000 4100 2000 1...4...2...A. .<br />
0000020: 4d00 6900 6e00 6500 6300 7200 6100 6600 M.i.n.e.c.r.a.f.<br />
0000030: 7400 2000 5300 6500 7200 7600 6500 7200 t. .S.e.r.v.e.r.<br />
0000040: 0000 3000 0000 3200 30 ..0...2.0<br />
<br />
== 1.4 - 1.5 ==<br />
<br />
Prior to the Minecraft 1.6, the client -> server operation is much simpler, and only sends <code>FE 01</code>, with none of the following data beginning <code>FA ...</code><br />
<br />
== Beta 1.8 - 1.3 ==<br />
<br />
Prior to Minecraft 1.4, the client only sends <code>FE</code>. <br />
<br />
Additionally, the response from the server only contains 3 fields delimited by <code>§</code>:<br />
<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 1700 4100 2000 4d00 6900 6e00 6500 ....A. .M.i.n.e.<br />
0000010: 6300 7200 6100 6600 7400 2000 5300 6500 c.r.a.f.t. .S.e.<br />
0000020: 7200 7600 6500 7200 a700 3000 a700 3100 r.v.e.r.§.0.§.1.<br />
0000030: 30 0<br />
<br />
<br />
== Sample code ==<br />
<br />
* [https://gist.github.com/1209061 Python]<br />
* [https://gist.github.com/6281388 Ruby]<br />
* [https://gist.github.com/5795159 PHP]<br />
* [https://gist.github.com/4574114 Java]<br />
* [https://gist.github.com/6223787 C#]</div>Drainedsoulhttps://wiki.vg/index.php?title=Data_types&diff=4517Data types2013-08-26T18:52:07Z<p>Drainedsoul: Minecraft actually uses UTF-16</p>
<hr />
<div>All data sent over the network is [http://en.wikipedia.org/wiki/Endianness#Big-endian big-endian], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<br />
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html DataInputStream] and [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataOutputStream.html DataOutputStream].<br />
<br />
{| class="wikitable"<br />
|- class="row0"<br />
| class="col0" |<br />
! class="col1" | Size<br />
! class="col2" | Range<br />
! class="col3" | Notes<br />
|- class="row1"<br />
! class="col0 centeralign" | bool<br />
| class="col1 centeralign" | 1<br />
| class="col2" | 0 or 1<br />
| class="col3" | Value can be either true (0x01) or false (0x00)<br />
|- class="row2"<br />
! class="col0 centeralign" | byte<br />
| class="col1 centeralign" | 1<br />
| class="col2" | -128 to 127<br />
| class="col3" | Signed, two's complement<br />
|- class="row3"<br />
! class="col0 centeralign" | short<br />
| class="col1 centeralign" | 2<br />
| class="col2" | -32768 to 32767<br />
| class="col3" | Signed, two's complement<br />
|- class="row4"<br />
! class="col0 centeralign" | int<br />
| class="col1 centeralign" | 4<br />
| class="col2" | -2147483648 to 2147483647<br />
| class="col3" | Signed, two's complement<br />
|- class="row5"<br />
! class="col0 centeralign" | long<br />
| class="col1 centeralign" | 8<br />
| class="col2" | -9223372036854775808 to 9223372036854775807<br />
| class="col3" | Signed, two's complement<br />
|- class="row6"<br />
! class="col0 centeralign" | float<br />
| class="col1 centeralign" | 4<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Single-precision 32-bit IEEE 754 floating point<br />
|- class="row7"<br />
! class="col0 centeralign" | double<br />
| class="col1 centeralign" | 8<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Double-precision 64-bit IEEE 754 floating point<br />
|- class="row8"<br />
! class="col0 centeralign" | string<br />
| class="col1 centeralign" | ≥ 2 <br />≤ 240<br />
| class="col2" | N/A<br />
| class="col3" | [http://en.wikipedia.org/wiki/UTF-16 UTF-16] big-endian string prefixed by a short containing the length of the string in [http://en.wikipedia.org/wiki/Code_unit code units] (as a UTF-16 code unit is 2 bytes, multiply the length by two to get the length in bytes). UTF-16 is a variable-width encoding so each [http://en.wikipedia.org/wiki/Code_point code point] may be 1 or 2 code units. Accordingly the specified length (in code units) does not necessarily map onto the logical length of the string (in code points).<br />
|- class="row9"<br />
! class="col0 centeralign" | metadata<br />
| class="col1 centeralign" | Varies<br />
| class="col2" | See [[Entities#Entity_Metadata_Format|this]]<br />
| class="Col3" | <br />
|}<br />
<br />
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double. The conversion from double to absolute integer is like so:<br />
<br />
abs_int = (int)double * 32;<br />
<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Data_types&diff=4204Data types2013-07-18T04:40:29Z<p>Drainedsoul: Terminology clean up</p>
<hr />
<div>All data sent over the network is [http://en.wikipedia.org/wiki/Endianness#Big-endian big-endian], that is the bytes are sent from most significant byte to least significant byte. The majority of everyday computers are little-endian, therefore it may be necessary to change the endianness before sending data over the network.<br />
<br />
Other than 'String' and 'Metadata', which are decoded with a custom function, these data formats are identical to those provided by the Java classes [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html DataInputStream] and [http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataOutputStream.html DataOutputStream].<br />
<br />
{| class="wikitable"<br />
|- class="row0"<br />
| class="col0" |<br />
! class="col1" | Size<br />
! class="col2" | Range<br />
! class="col3" | Notes<br />
|- class="row1"<br />
! class="col0 centeralign" | byte<br />
| class="col1 centeralign" | 1<br />
| class="col2" | -128 to 127<br />
| class="col3" | Signed, two's complement<br />
|- class="row2"<br />
! class="col0 centeralign" | short<br />
| class="col1 centeralign" | 2<br />
| class="col2" | -32768 to 32767<br />
| class="col3" | Signed, two's complement<br />
|- class="row3"<br />
! class="col0 centeralign" | int<br />
| class="col1 centeralign" | 4<br />
| class="col2" | -2147483648 to 2147483647<br />
| class="col3" | Signed, two's complement<br />
|- class="row4"<br />
! class="col0 centeralign" | long<br />
| class="col1 centeralign" | 8<br />
| class="col2" | -9223372036854775808 to 9223372036854775807<br />
| class="col3" | Signed, two's complement<br />
|- class="row5"<br />
! class="col0 centeralign" | float<br />
| class="col1 centeralign" | 4<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Single-precision 32-bit IEEE 754 floating point<br />
|- class="row6"<br />
! class="col0 centeralign" | double<br />
| class="col1 centeralign" | 8<br />
| class="col2" |<br />
See [http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 this]<br />
| class="col3" | Double-precision 64-bit IEEE 754 floating point<br />
|- class="row7"<br />
! class="col0 centeralign" | string<br />
| class="col1 centeralign" | ≥ 2 <br />≤ 240<br />
| class="col2" | N/A<br />
| class="col3" | [http://en.wikipedia.org/wiki/UTF-16/UCS-2 UCS-2] big-endian string prefixed by a short containing the length of the string in [http://en.wikipedia.org/wiki/Code_point code points]. UCS-2 is a fixed-width encoding with each code point represented by a 16-bit code unit. As it is limited to 16 bits it can only represent code points in the [https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane Basic Multilangual Plane] (U+0000 through U+FFFF inclusive).<br />
|- class="row8"<br />
! class="col0 centeralign" | bool<br />
| class="col1 centeralign" | 1<br />
| class="col2" | 0 or 1<br />
| class="col3" | Value can be either true (0x01) or false (0x00)<br />
|- class="row9"<br />
! class="col0 centeralign" | metadata<br />
| class="col1 centeralign" | Varies<br />
| class="col2" | See [[Entities#Entity_Metadata_Format|this]]<br />
| class="Col3" | <br />
|}<br />
<br />
Some data may be stored as an "absolute integer", which is a more precise kind of integer, and a less precise kind of double. The conversion from double to absolute integer is like so:<br />
<br />
abs_int = (int)double * 32;<br />
<br />
And back again:<br />
<br />
double = (double)abs_int / 32;<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Server_List_Ping&diff=3830Server List Ping2013-06-15T11:22:17Z<p>Drainedsoul: Added an example ping transcript</p>
<hr />
<div>Minecraft supports querying the MOTD, player count, max players and server version via the usual port. Unlike [[Query]], the server list ping interface is always enabled.<br />
<br />
== Client -> Server ==<br />
<br />
The client initiates a TCP connection to the minecraft server on the standard port. Instead of doing auth and logging in (as detailed in [[Protocol Encryption]]), it sends the two byte sequence <code>FE 01</code>. This is a [[Protocol#Server_List_Ping_.280xFE.29|0xFE server list ping]] packet. If the second byte (the 0x01) is missing, the server waits about 1000ms then replies with the [[#Server_-.3E_Client_format_used_in_1.3_and_earlier|Server -> Client format used in 1.3 and earlier]].<br />
<br />
== Server -> Client ==<br />
<br />
The server responds with a [[Protocol#Disconnect.2FKick_.280xFF.29|0xFF kick]] packet. The packet begins with a single byte identifier <code>ff</code>, then a two-byte big endian short giving the length of the proceeding string in characters. You can actually ignore the length because the server closes the connection after the response is sent.<br />
<br />
After the first 3 bytes, the packet is a big-endian UCS-2 string. It begins with two characters: <code>§1</code>, followed by a null character. On the wire these look like <code>00 a7 00 31 00 00</code>.<br />
<br />
The remainder is null character (that is <code>00 00</code>) delimited fields:<br />
<br />
# Protocol version (e.g. <code>47</code>)<br />
# Minecraft server version (e.g. <code>1.4.2</code>)<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 2300 a700 3100 0000 3400 3700 0000 ....§.1...4.7...<br />
0000010: 3100 2e00 3400 2e00 3200 0000 4100 2000 1...4...2...A. .<br />
0000020: 4d00 6900 6e00 6500 6300 7200 6100 6600 M.i.n.e.c.r.a.f.<br />
0000030: 7400 2000 5300 6500 7200 7600 6500 7200 t. .S.e.r.v.e.r.<br />
0000040: 0000 3000 0000 3200 30 ..0...2.0<br />
<br />
== Example ==<br />
<br />
A parsed transcript of a server list ping follows:<br />
<br />
127.0.0.1:26603 connected, there is now 1 client connected<br />
====PROTOCOL ANALYSIS====<br />
127.0.0.1:26603 ==> Server - Packet of type 0xFE<br />
====2 BYTES====<br />
0xFE 0x01<br />
====PAYLOAD====<br />
#1 - Signed Byte: 1<br />
127.0.0.1:26603 pinged<br />
====PROTOCOL ANALYSIS====<br />
Server ==> 127.0.0.1:26603 - Packet of type 0xFF<br />
====59 BYTES====<br />
0xFF 0x00 0x1C 0x00 0xA7 0x00 0x31 0x00<br />
0x00 0x00 0x36 0x00 0x31 0x00 0x00 0x00<br />
0x31 0x00 0x2E 0x00 0x35 0x00 0x2E 0x00<br />
0x32 0x00 0x00 0x00 0x54 0x00 0x65 0x00<br />
0x73 0x00 0x74 0x00 0x20 0x00 0x53 0x00<br />
0x65 0x00 0x72 0x00 0x76 0x00 0x65 0x00<br />
0x72 0x00 0x00 0x00 0x30 0x00 0x00 0x00<br />
0x32 0x00 0x30<br />
====PAYLOAD====<br />
#1 - Unicode String (28 graphemes, 28 code points): "§1 61 1.5.2 Test Server 0 2<br />
0"<br />
127.0.0.1:26603 disconnected, there are now 0 clients connected<br />
<br />
'''NOTE''': <code>§1 61 1.5.2 Test Server 0 20</code> is actually <code>§1\061\01.5.2\0Test Server\00\020</code> where <code>\0</code> is the null character (i.e. U+0000).<br />
<br />
== Server -> Client format used in 1.3 and earlier ==<br />
<br />
The packet-structure is the same as above. Only the content of the big-endian UCS-2 string is different.<br />
<br />
This one contains 3 fields delimited by <code>§</code>:<br />
<br />
# Message of the day (e.g. <code>A Minecraft Server</code>)<br />
# Current player count<br />
# Max players<br />
<br />
The entire packet looks something like this:<br />
<br />
<---> first character<br />
0000000: ff00 1700 4100 2000 4d00 6900 6e00 6500 ....A. .M.i.n.e.<br />
0000010: 6300 7200 6100 6600 7400 2000 5300 6500 c.r.a.f.t. .S.e.<br />
0000020: 7200 7600 6500 7200 a700 3000 a700 3100 r.v.e.r.§.0.§.1.<br />
0000030: 30 0<br />
<br />
<br />
== Sample code ==<br />
<br />
* [https://gist.github.com/1209061 Python]<br />
* [http://forums.bukkit.org/threads/solved-minecraft-server-list-ping-php-script-for-1-4.108096/#post-1395553 PHP]<br />
* [https://gist.github.com/4574114 Java]</div>Drainedsoulhttps://wiki.vg/index.php?title=Protocol_Encryption&diff=3432Protocol Encryption2013-06-15T11:09:48Z<p>Drainedsoul: Added an example handshake transcript</p>
<hr />
<div>As of 12w17a, minecraft implements SSL-like encryption.<br />
<br />
== Overview ==<br />
<br />
#Client connects to server<br />
#'''C->S''' 0x02 handshake<br />
#'''S->C''' 0xFD encryption request - server sends its server id string, public key, and 4 random bytes<br />
#Client generates symmetric key (shared secret)<br />
#Client authenticates via [[Session|session.minecraft.net]].<br />
#Client encrypts these 4 bytes with the servers public key.<br />
#'''C->S''' 0xFC encryption response - client encrypts shared secret with server's public key and sends along with encrypted 4 bytes<br />
#Server checks that the encrypted bytes match<br />
#Server decrypts shared secret with its private key<br />
#Server checks player authenticity via session.minecraft.net<br />
#'''S->C''' 0xFC encryption response - empty payload meaning two zero length byte arrays and two zero shorts<br />
#Server enables AES/CFB8 stream encryption<br />
#Client enables AES/CFB8 stream encryption<br />
#'''C->S''' 0xCD - Payload of 0 (byte)<br />
#'''S->C''' 0x01 login<br />
#see [[Protocol FAQ]] to get information about what happens next.<br />
<br />
==Server ID String==<br />
<br />
The server ID string is a randomly-generated string of characters with a maximum length of 20 code points (the client disconnects with an exception if the length is longer than 20).<br />
<br />
The client appears to arrive at incorrect hashes if the server ID string contains certain unprintable characters, so for consistent results only characters with code points in the range U+0021-U+007E (inclusive) should be sent. This range corresponds to all of ASCII with the exception of the space character (U+0020) and all control characters (U+0000-U+001F, U+007F).<br />
<br />
The client appears to arrive at incorrect hashes if the server ID string is too short. 15 to 20 (inclusive) length strings have been observed from the Notchian server and confirmed to work as of 1.5.2.<br />
<br />
== Key Exchange ==<br />
<br />
The server generates a 1024-bit RSA keypair on startup. The key, when packed into a 0xFD packet, is in ASN.1 format as defined by x.509.<br />
The ASN.1 structure looks as follows<br />
<br />
SubjectPublicKeyInfo ::= SEQUENCE {<br />
algorithm SEQUENCE {<br />
algorithm OBJECT IDENTIFIER<br />
parameters ANY OPTIONAL<br />
}<br />
subjectPublicKey BITSTRING<br />
}<br />
<br />
SubjectPublicKey ::= SEQUENCE {<br />
modulus INTEGER<br />
publicExponent INTEGER<br />
}<br />
<br />
If you're struggling to import this using a crypto library, you can convert it to common PEM by base64-encoding and wrapping in '-----BEGIN PUBLIC KEY-----' and '-----END PUBLIC KEY-----'.<br />
<br />
== Symmetric Encryption ==<br />
<br />
On receipt of a 0xFD from the server, the client will generate a 16-byte shared secret, to be used with the AES/CFB8 stream cipher. It then encrypts it with the server's public key (PKCS#1 v1.5 padded), and also encrypts the token received in the 0xFD packet in the same way, then sends both to the server in a 0xFC packet.<br />
<br />
The server decrypts the shared secret and token using its private key, and checks if the token is the same. It then sends a 0xFC to the client with an empty payload, and enables AES/CFB8 encryption. For the Initial Vector (IV) and AES setup, both sides use the secret key. Similarly, the client will also enable encryption upon receipt of the empty 0xFC. From this point forward, everything is encrypted.<br />
<br />
== Authentication ==<br />
<br />
Both server and client need to make a request to session.minecraft.net if the server is in online-mode.<br />
<br />
=== Client ===<br />
<br />
After generating the shared secret, the client generates the following hash:<br />
<br />
sha1 := Sha1()<br />
sha1.update(ASCII encoding of the server id string from 0xFD) <br />
sha1.update(shared secret) <br />
sha1.update(server's encoded public key from 0xFD) <br />
hash := sha1.hexdigest() # String of hex characters<br />
<br />
[[File:Icon_exclaim.gif|:!:]] Note that the Sha1.hexdigest() method used by minecraft removes leading zeros and uses the two's-complement of negative numbers prefixed with a minus sign:<br />
<br />
sha1(Notch) : 4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48<br />
sha1(jeb_) : -7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1<br />
sha1(simon) : 88e16a1019277b15d58faf0541e11910eb756f6<br />
<br />
The resulting hash is then sent via an HTTP GET request to<br />
<nowiki>http://session.minecraft.net/game/joinserver.jsp?user=</nowiki>''username''&sessionId=''[[Session#Login|user_session]]''&serverId=''hash''<br />
If it returns '''OK''' then continue, otherwise stop<br />
<br />
=== Server ===<br />
<br />
After decrypting the shared secret in the second 0xFC, the server generates the login hash as above and sends it to<br />
<nowiki>http://session.minecraft.net/game/checkserver.jsp?user=</nowiki>''username''&serverId=''hash''<br />
<br />
If the response is '''YES''' then the client is authenticated and allowed to join. Otherwise the client will/should be [[Protocol#Disconnect.2FKick_.280xFF.29|kicked]] (unencrypted) with "Failed to verify username!"<br />
<br />
=== Sample Code ===<br />
<br />
Examples of generating Java-style hex digests:<br />
<br />
* C#: https://gist.github.com/404223052379e82f91e6<br />
* node.js: https://gist.github.com/4425843<br />
* Go: https://gist.github.com/toqueteos/5372776<br />
<br />
== Example ==<br />
<br />
A parsed transcript of a successful protocol encryption handshake follows:<br />
<br />
127.0.0.1:43733 connected, there is now 1 client connected<br />
====PROTOCOL ANALYSIS====<br />
127.0.0.1:43733 ==> Server - Packet of type 0x02<br />
====50 BYTES====<br />
0x02 0x3D 0x00 0x0B 0x00 0x44 0x00 0x72<br />
0x00 0x61 0x00 0x69 0x00 0x6E 0x00 0x65<br />
0x00 0x64 0x00 0x73 0x00 0x6F 0x00 0x75<br />
0x00 0x6C 0x00 0x09 0x00 0x6C 0x00 0x6F<br />
0x00 0x63 0x00 0x61 0x00 0x6C 0x00 0x68<br />
0x00 0x6F 0x00 0x73 0x00 0x74 0x00 0x00<br />
0x2D 0x85<br />
====PAYLOAD====<br />
#1 - Signed Byte: 61<br />
#2 - Unicode String (11 graphemes, 11 code points): "Drainedsoul"<br />
#3 - Unicode String (9 graphemes, 9 code points): "localhost"<br />
#4 - 32-bit Signed Integer: 11653<br />
====PROTOCOL ANALYSIS====<br />
Server ==> 127.0.0.1:43733 - Packet of type 0xFD<br />
====205 BYTES====<br />
0xFD 0x00 0x10 0x00 0x4E 0x00 0x77 0x00<br />
0x5D 0x00 0x31 0x00 0x51 0x00 0x61 0x00<br />
0x43 0x00 0x3C 0x00 0x6F 0x00 0x3A 0x00<br />
0x6C 0x00 0x2E 0x00 0x5C 0x00 0x65 0x00<br />
0x53 0x00 0x39 0x00 0xA2 0x30 0x81 0x9F<br />
0x30 0x0D 0x06 0x09 0x2A 0x86 0x48 0x86<br />
0xF7 0x0D 0x01 0x01 0x01 0x05 0x00 0x03<br />
0x81 0x8D 0x00 0x30 0x81 0x89 0x02 0x81<br />
0x81 0x00 0x9D 0x09 0x76 0x71 0x45 0x24<br />
0x18 0x53 0x5F 0x32 0x5A 0xD5 0xBB 0x26<br />
0x43 0x2C 0x97 0xBB 0xB3 0xF4 0x03 0x96<br />
0xEA 0xF1 0xAD 0xA6 0xC9 0x41 0x7B 0x01<br />
0x8F 0x66 0xED 0x92 0x4B 0xB7 0x17 0x2C<br />
0x65 0x5C 0xD2 0x42 0x35 0x0C 0x8A 0x8C<br />
0xC3 0xE1 0x5C 0x76 0x0E 0x43 0x97 0x17<br />
0xEE 0x9E 0xEF 0x4F 0x4E 0x2D 0xFC 0x2D<br />
0xE6 0x92 0x0B 0x7E 0xA0 0x56 0xB5 0xB7<br />
0x18 0x59 0x57 0x74 0x28 0x5C 0xA1 0x88<br />
0xC4 0xE6 0x60 0xDF 0x64 0x3A 0x2C 0x0E<br />
0x5C 0x7D 0xB9 0x7C 0xF9 0xFB 0xA2 0x21<br />
0xC5 0x0B 0x36 0x7D 0xDE 0x8A 0xC9 0xC5<br />
0x09 0xA0 0x2F 0xA0 0x25 0x8A 0x26 0xDB<br />
0x0B 0x82 0xC8 0x60 0xCB 0x58 0x02 0xEC<br />
0xBB 0xFE 0xBC 0x35 0x3F 0x40 0x9C 0x96<br />
0xF4 0x5F 0x02 0x03 0x01 0x00 0x01 0x00<br />
0x04 0xED 0x85 0x14 0xD6<br />
====PAYLOAD====<br />
#1 - Unicode String (16 graphemes, 16 code points): "Nw]1QaC<o:l.\eS9"<br />
#2 - Array of bytes (162 bytes):<br />
0x30 0x81 0x9F 0x30 0x0D 0x06 0x09 0x2A<br />
0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x01<br />
0x05 0x00 0x03 0x81 0x8D 0x00 0x30 0x81<br />
0x89 0x02 0x81 0x81 0x00 0x9D 0x09 0x76<br />
0x71 0x45 0x24 0x18 0x53 0x5F 0x32 0x5A<br />
0xD5 0xBB 0x26 0x43 0x2C 0x97 0xBB 0xB3<br />
0xF4 0x03 0x96 0xEA 0xF1 0xAD 0xA6 0xC9<br />
0x41 0x7B 0x01 0x8F 0x66 0xED 0x92 0x4B<br />
0xB7 0x17 0x2C 0x65 0x5C 0xD2 0x42 0x35<br />
0x0C 0x8A 0x8C 0xC3 0xE1 0x5C 0x76 0x0E<br />
0x43 0x97 0x17 0xEE 0x9E 0xEF 0x4F 0x4E<br />
0x2D 0xFC 0x2D 0xE6 0x92 0x0B 0x7E 0xA0<br />
0x56 0xB5 0xB7 0x18 0x59 0x57 0x74 0x28<br />
0x5C 0xA1 0x88 0xC4 0xE6 0x60 0xDF 0x64<br />
0x3A 0x2C 0x0E 0x5C 0x7D 0xB9 0x7C 0xF9<br />
0xFB 0xA2 0x21 0xC5 0x0B 0x36 0x7D 0xDE<br />
0x8A 0xC9 0xC5 0x09 0xA0 0x2F 0xA0 0x25<br />
0x8A 0x26 0xDB 0x0B 0x82 0xC8 0x60 0xCB<br />
0x58 0x02 0xEC 0xBB 0xFE 0xBC 0x35 0x3F<br />
0x40 0x9C 0x96 0xF4 0x5F 0x02 0x03 0x01<br />
0x00 0x01<br />
#3 - Array of bytes (4 bytes):<br />
0xED 0x85 0x14 0xD6<br />
====PROTOCOL ANALYSIS====<br />
127.0.0.1:43733 ==> Server - Packet of type 0xFC<br />
====261 BYTES====<br />
0xFC 0x00 0x80 0x9B 0xD1 0xD7 0xA8 0xDB<br />
0x54 0x49 0x8F 0x41 0xD5 0xA3 0x74 0x18<br />
0xBD 0x8D 0x09 0xEA 0x45 0xFC 0x0F 0x3F<br />
0x9B 0xE4 0xF9 0xAC 0xC5 0x7B 0xF6 0x16<br />
0xBB 0xFA 0x36 0x51 0xF9 0x19 0xAB 0x72<br />
0x2B 0xBA 0x46 0x6C 0x8D 0xB0 0x2D 0x53<br />
0x5F 0xA5 0xD4 0x17 0x46 0x0E 0xD7 0xC1<br />
0xAA 0x5D 0xC7 0x73 0x51 0xDA 0x3F 0xD7<br />
0x5E 0xF6 0x96 0xF9 0x10 0xB2 0x1C 0x0D<br />
0xAA 0x1E 0x61 0x37 0xFB 0x3C 0x66 0x77<br />
0x20 0xCB 0xF7 0x3C 0x55 0xE5 0x9E 0xC1<br />
0x28 0x63 0xD1 0xD7 0xF6 0xEE 0x1E 0x2C<br />
0x20 0x72 0x98 0x7E 0xF2 0x7D 0xDF 0xFE<br />
0x5A 0x25 0x3C 0x22 0xC0 0xCF 0x86 0xB3<br />
0x02 0x97 0xB1 0x80 0x97 0xA1 0x92 0xDA<br />
0xD2 0x44 0xB1 0xDA 0x0F 0x1C 0x30 0x96<br />
0x98 0x0B 0xB7 0x00 0x80 0x78 0x85 0x42<br />
0xF7 0xF8 0x2F 0x00 0xDB 0xBF 0x2E 0x22<br />
0x33 0x10 0x6C 0x19 0xE3 0x16 0x8F 0x36<br />
0x16 0xE3 0xD9 0x86 0x67 0x52 0x04 0x57<br />
0xB6 0x4F 0x57 0x8C 0xB4 0x02 0x18 0x6D<br />
0x16 0xC6 0xB5 0x95 0xBC 0xE6 0xEA 0x76<br />
0x10 0x7A 0xB9 0xE3 0xBD 0x3C 0x50 0xEA<br />
0x42 0xDF 0x47 0x05 0x3F 0xCF 0xD5 0x70<br />
0xF4 0xAB 0xB5 0x07 0x90 0xA2 0x84 0x12<br />
0x79 0x65 0x03 0x2A 0xB6 0x6B 0x0A 0xA8<br />
0x90 0x8B 0xFE 0xCC 0x4E 0x04 0x35 0xA2<br />
0xDD 0x08 0xBF 0xDD 0x29 0xAF 0x50 0xFD<br />
0x2B 0x73 0xE1 0x6A 0xED 0xE8 0xE2 0x27<br />
0x8F 0x0B 0xD5 0x0D 0xBC 0x9B 0x47 0x16<br />
0x92 0x7B 0xD2 0xE6 0xD7 0xF1 0x3A 0xAE<br />
0x3D 0x14 0xA9 0xC3 0xF2 0x96 0x8A 0x54<br />
0x24 0x29 0xA3 0x53 0x55<br />
====PAYLOAD====<br />
#1 - Array of bytes (128 bytes):<br />
0x9B 0xD1 0xD7 0xA8 0xDB 0x54 0x49 0x8F<br />
0x41 0xD5 0xA3 0x74 0x18 0xBD 0x8D 0x09<br />
0xEA 0x45 0xFC 0x0F 0x3F 0x9B 0xE4 0xF9<br />
0xAC 0xC5 0x7B 0xF6 0x16 0xBB 0xFA 0x36<br />
0x51 0xF9 0x19 0xAB 0x72 0x2B 0xBA 0x46<br />
0x6C 0x8D 0xB0 0x2D 0x53 0x5F 0xA5 0xD4<br />
0x17 0x46 0x0E 0xD7 0xC1 0xAA 0x5D 0xC7<br />
0x73 0x51 0xDA 0x3F 0xD7 0x5E 0xF6 0x96<br />
0xF9 0x10 0xB2 0x1C 0x0D 0xAA 0x1E 0x61<br />
0x37 0xFB 0x3C 0x66 0x77 0x20 0xCB 0xF7<br />
0x3C 0x55 0xE5 0x9E 0xC1 0x28 0x63 0xD1<br />
0xD7 0xF6 0xEE 0x1E 0x2C 0x20 0x72 0x98<br />
0x7E 0xF2 0x7D 0xDF 0xFE 0x5A 0x25 0x3C<br />
0x22 0xC0 0xCF 0x86 0xB3 0x02 0x97 0xB1<br />
0x80 0x97 0xA1 0x92 0xDA 0xD2 0x44 0xB1<br />
0xDA 0x0F 0x1C 0x30 0x96 0x98 0x0B 0xB7<br />
#2 - Array of bytes (128 bytes):<br />
0x78 0x85 0x42 0xF7 0xF8 0x2F 0x00 0xDB<br />
0xBF 0x2E 0x22 0x33 0x10 0x6C 0x19 0xE3<br />
0x16 0x8F 0x36 0x16 0xE3 0xD9 0x86 0x67<br />
0x52 0x04 0x57 0xB6 0x4F 0x57 0x8C 0xB4<br />
0x02 0x18 0x6D 0x16 0xC6 0xB5 0x95 0xBC<br />
0xE6 0xEA 0x76 0x10 0x7A 0xB9 0xE3 0xBD<br />
0x3C 0x50 0xEA 0x42 0xDF 0x47 0x05 0x3F<br />
0xCF 0xD5 0x70 0xF4 0xAB 0xB5 0x07 0x90<br />
0xA2 0x84 0x12 0x79 0x65 0x03 0x2A 0xB6<br />
0x6B 0x0A 0xA8 0x90 0x8B 0xFE 0xCC 0x4E<br />
0x04 0x35 0xA2 0xDD 0x08 0xBF 0xDD 0x29<br />
0xAF 0x50 0xFD 0x2B 0x73 0xE1 0x6A 0xED<br />
0xE8 0xE2 0x27 0x8F 0x0B 0xD5 0x0D 0xBC<br />
0x9B 0x47 0x16 0x92 0x7B 0xD2 0xE6 0xD7<br />
0xF1 0x3A 0xAE 0x3D 0x14 0xA9 0xC3 0xF2<br />
0x96 0x8A 0x54 0x24 0x29 0xA3 0x53 0x55<br />
====PROTOCOL ANALYSIS====<br />
HTTP request ==> <nowiki>http://session.minecraft.net/game/checkserver.jsp?user=Draineds</nowiki><br />
oul&serverId=-219245c9f4bce438ee84e84b28514ced1cd2846b<br />
====PROTOCOL ANALYSIS====<br />
HTTP response <== <nowiki>http://session.minecraft.net/game/checkserver.jsp?user=Drained</nowiki><br />
soul&serverId=-219245c9f4bce438ee84e84b28514ced1cd2846b - Status: 200 - Time ela<br />
psed: 279902765ns - Response body (3 graphemes, 3 code points):<br />
YES<br />
====PROTOCOL ANALYSIS====<br />
Server ==> 127.0.0.1:43733 - Packet of type 0xFC<br />
====5 BYTES====<br />
0xFC 0x00 0x00 0x00 0x00<br />
====PAYLOAD====<br />
#1 - Array of bytes (0 bytes):<br />
<br />
#2 - Array of bytes (0 bytes):<br />
<br />
====ENCRYPTION ENABLED====<br />
Encryption enabled with key:<br />
0x6C 0xBC 0x2E 0x17 0x45 0xBD 0x65 0xDF<br />
0xA0 0x12 0x85 0x8F 0x00 0x87 0xAA 0x74<br />
Encryption enabled with IV:<br />
0x6C 0xBC 0x2E 0x17 0x45 0xBD 0x65 0xDF<br />
0xA0 0x12 0x85 0x8F 0x00 0x87 0xAA 0x74<br />
127.0.0.1 : 43733 logged in as Drainedsoul<br />
====PROTOCOL ANALYSIS====<br />
127.0.0.1:43733 ==> Server - Packet of type 0xCD<br />
====2 BYTES====<br />
0xCD 0x00<br />
<br />
== Additional Links ==<br />
[https://gist.github.com/3900517 Encrypt shared secret using OpenSSL]<br />
<br />
[http://pastebin.com/8eYyKZn6 Generate RSA-Keys and building the ASN.1v8 structure of the x.509 certificate using Crypto++]<br />
<br />
[http://pastebin.com/7Jvaama1 Decrypt shared secret using Crypto++]<br />
<br />
[http://pastebin.com/MjvR0T98 De/Encrypt data via AES using Crypto++]<br />
<br />
[https://github.com/SirCmpwn/Craft.Net/blob/master/Craft.Net/AesStream.cs C# AES/CFB support with bouncy castle on Mono]<br />
<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=Protocol_Encryption&diff=3431Protocol Encryption2013-06-14T08:38:32Z<p>Drainedsoul: Server ID string details (own experimentation/protocol analysis)</p>
<hr />
<div>As of 12w17a, minecraft implements SSL-like encryption.<br />
<br />
== Overview ==<br />
<br />
#Client connects to server<br />
#'''C->S''' 0x02 handshake<br />
#'''S->C''' 0xFD encryption request - server sends its server id string, public key, and 4 random bytes<br />
#Client generates symmetric key (shared secret)<br />
#Client authenticates via [[Session|session.minecraft.net]].<br />
#Client encrypts these 4 bytes with the servers public key.<br />
#'''C->S''' 0xFC encryption response - client encrypts shared secret with server's public key and sends along with encrypted 4 bytes<br />
#Server checks that the encrypted bytes match<br />
#Server decrypts shared secret with its private key<br />
#Server checks player authenticity via session.minecraft.net<br />
#'''S->C''' 0xFC encryption response - empty payload meaning two zero length byte arrays and two zero shorts<br />
#Server enables AES/CFB8 stream encryption<br />
#Client enables AES/CFB8 stream encryption<br />
#'''C->S''' 0xCD - Payload of 0 (byte)<br />
#'''S->C''' 0x01 login<br />
#see [[Protocol FAQ]] to get information about what happens next.<br />
<br />
==Server ID String==<br />
<br />
The server ID string is a randomly-generated string of characters with a maximum length of 20 code points (the client disconnects with an exception if the length is longer than 20).<br />
<br />
The client appears to arrive at incorrect hashes if the server ID string contains certain unprintable characters, so for consistent results only characters with code points in the range U+0021-U+007E (inclusive) should be sent. This range corresponds to all of ASCII with the exception of the space character (U+0020) and all control characters (U+0000-U+001F, U+007F).<br />
<br />
The client appears to arrive at incorrect hashes if the server ID string is too short. 15 to 20 (inclusive) length strings have been observed from the Notchian server and confirmed to work as of 1.5.2.<br />
<br />
== Key Exchange ==<br />
<br />
The server generates a 1024-bit RSA keypair on startup. The key, when packed into a 0xFD packet, is in ASN.1 format as defined by x.509.<br />
The ASN.1 structure looks as follows<br />
<br />
SubjectPublicKeyInfo ::= SEQUENCE {<br />
algorithm SEQUENCE {<br />
algorithm OBJECT IDENTIFIER<br />
parameters ANY OPTIONAL<br />
}<br />
subjectPublicKey BITSTRING<br />
}<br />
<br />
SubjectPublicKey ::= SEQUENCE {<br />
modulus INTEGER<br />
publicExponent INTEGER<br />
}<br />
<br />
If you're struggling to import this using a crypto library, you can convert it to common PEM by base64-encoding and wrapping in '-----BEGIN PUBLIC KEY-----' and '-----END PUBLIC KEY-----'.<br />
<br />
== Symmetric Encryption ==<br />
<br />
On receipt of a 0xFD from the server, the client will generate a 16-byte shared secret, to be used with the AES/CFB8 stream cipher. It then encrypts it with the server's public key (PKCS#1 v1.5 padded), and also encrypts the token received in the 0xFD packet in the same way, then sends both to the server in a 0xFC packet.<br />
<br />
The server decrypts the shared secret and token using its private key, and checks if the token is the same. It then sends a 0xFC to the client with an empty payload, and enables AES/CFB8 encryption. For the Initial Vector (IV) and AES setup, both sides use the secret key. Similarly, the client will also enable encryption upon receipt of the empty 0xFC. From this point forward, everything is encrypted.<br />
<br />
== Authentication ==<br />
<br />
Both server and client need to make a request to session.minecraft.net if the server is in online-mode.<br />
<br />
=== Client ===<br />
<br />
After generating the shared secret, the client generates the following hash:<br />
<br />
sha1 := Sha1()<br />
sha1.update(ASCII encoding of the server id string from 0xFD) <br />
sha1.update(shared secret) <br />
sha1.update(server's encoded public key from 0xFD) <br />
hash := sha1.hexdigest() # String of hex characters<br />
<br />
[[File:Icon_exclaim.gif|:!:]] Note that the Sha1.hexdigest() method used by minecraft removes leading zeros and uses the two's-complement of negative numbers prefixed with a minus sign:<br />
<br />
sha1(Notch) : 4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48<br />
sha1(jeb_) : -7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1<br />
sha1(simon) : 88e16a1019277b15d58faf0541e11910eb756f6<br />
<br />
The resulting hash is then sent via an HTTP GET request to<br />
<nowiki>http://session.minecraft.net/game/joinserver.jsp?user=</nowiki>''username''&sessionId=''[[Session#Login|user_session]]''&serverId=''hash''<br />
If it returns '''OK''' then continue, otherwise stop<br />
<br />
=== Server ===<br />
<br />
After decrypting the shared secret in the second 0xFC, the server generates the login hash as above and sends it to<br />
<nowiki>http://session.minecraft.net/game/checkserver.jsp?user=</nowiki>''username''&serverId=''hash''<br />
<br />
If the response is '''YES''' then the client is authenticated and allowed to join. Otherwise the client will/should be [[Protocol#Disconnect.2FKick_.280xFF.29|kicked]] (unencrypted) with "Failed to verify username!"<br />
<br />
=== Sample Code ===<br />
<br />
Examples of generating Java-style hex digests:<br />
<br />
* C#: https://gist.github.com/404223052379e82f91e6<br />
* node.js: https://gist.github.com/4425843<br />
* Go: https://gist.github.com/toqueteos/5372776<br />
<br />
== Additional Links ==<br />
[https://gist.github.com/3900517 Encrypt shared secret using OpenSSL]<br />
<br />
[http://pastebin.com/8eYyKZn6 Generate RSA-Keys and building the ASN.1v8 structure of the x.509 certificate using Crypto++]<br />
<br />
[http://pastebin.com/7Jvaama1 Decrypt shared secret using Crypto++]<br />
<br />
[http://pastebin.com/MjvR0T98 De/Encrypt data via AES using Crypto++]<br />
<br />
[https://github.com/SirCmpwn/Craft.Net/blob/master/Craft.Net/AesStream.cs C# AES/CFB support with bouncy castle on Mono]<br />
<br />
<br />
[[Category:Protocol Details]]<br />
[[Category:Minecraft Modern]]</div>Drainedsoulhttps://wiki.vg/index.php?title=NBT&diff=2031NBT2013-05-03T04:10:27Z<p>Drainedsoul: Describing integer types by language- and/or platform-specific types is not useful. Integers have numerical widths to avoid precisely this problem.</p>
<hr />
<div>The Named Binary Tag (NBT) file format is an extremely simple, albiet annoying (did we really need yet ''another'' format?)<sup>[See Discussion]</sup> structured binary format used by the [http://www.minecraft.net Minecraft] game for a variety of things. Due to this, several third-party utilities now also utilize the format. You may find example files at: http://wiki.vg/nbt/<br />
<br />
== Current Uses ==<br />
The NBT format is currently used in several places, chiefly:<br />
* In the [[Protocol]] as part of [[Slot Data]]<br />
* Multiplayer saved server list (<code>servers.dat</code>).<br />
* Player data (both single player and multiplayer, one file per player). This includes such things as inventory and location.<br />
* Saved worlds (both single player and multiplayer).<br />
** World index file (<code>level.dat</code>) that contains general information (spawn point, time of day, etc...)<br />
** Chunk data (see [[Region Files]])<br />
<br />
Unfortunately, the NBT files you can encounter as a developer will be stored in three different ways, just to make things interesting.<br />
* Uncompressed,<br />
* [[wikipedia:Gzip|gzip'd]],<br />
* [[wikipedia:Zlib|zlib'd]] (aka DEFLATE with a few bytes extra)<br />
<br />
=== Libraries ===<br />
There are many, many libraries for manipulating NBT, written in several languages, and often several per language. For example,<br />
<br />
* [https://github.com/FliPPeh/cNBT C],<br />
* [https://github.com/fragmer/fNbt C#], <br />
* [https://github.com/Dav1dde/nbd D],<br />
* [https://github.com/toqueteos/minero/tree/master/proto/nbt Go],<br />
* [https://github.com/sjmulder/nbt-js Javascript], <br />
* [https://github.com/TheFrozenFire/PHP-NBT-Decoder-Encoder PHP],<br />
* [https://github.com/twoolie/NBT Python],<br />
* [https://github.com/mental/nbtfile Ruby], <br />
* You get the idea...<br />
<br />
Unless you have specific goals or licence requirements, it is ''extremely recommended'' to go with one of the existing libraries.<br />
<br />
=== Utilities ===<br />
Almost every 3rd-party Minecraft application uses NBT on some level. There also exist several dedicated NBT editors, which will likely be useful to you if you are developing an NBT library of your own. These include:<br />
* [http://www.minecraftforum.net/topic/6661-nbtedit/ NBTEdit] (C#, Mono-capable), one of the very first NBT editors.<br />
* [http://gerritg.de/?p=152 NEINedit] (Obj-C), an OS X specific editor.<br />
* [https://bitbucket.org/zzzeek/nbt2yaml nbt2yaml] (Python), provides command-line editing of NBT via the YAML format, as well as a fast and minimalist NBT parsing/rendering API.<br />
<br />
== Specification ==<br />
The NBT file format is extremely simple, and writing a library capable of reading/writing it is a simple affair, usually taking no more than an hour, depending on your skills and language of choice. There are 11 datatypes supported by this format, and one type used to close compound tags. It is strongly advised to read this entire section (no skimming!) or you '''will''' run into issues.<br />
<br />
<br />
{| class="wikitable"<br />
|-<br />
! Type ID<br />
! Type Name<br />
! Payload Size (Bytes)<br />
! Description<br />
|-<br />
| 0 <br />
| TAG_End <br />
| 0 <br />
| This tag serves no purpose but to signify the end of an open TAG_Compound. In most libraries, this type is abstracted away and never seen. TAG_End is not named.<br />
|-<br />
| 1<br />
| TAG_Byte<br />
| 1<br />
| A single signed byte<br />
|-<br />
| 2<br />
| TAG_Short<br />
| 2<br />
| A single signed, big endian 16 bit integer<br />
|-<br />
| 3<br />
| TAG_Int<br />
| 4<br />
| A single signed, big endian 32 bit integer<br />
|-<br />
| 4<br />
| TAG_Long<br />
| 8<br />
| A single signed, big endian 64 bit integer<br />
|-<br />
| 5<br />
| TAG_Float<br />
| 4<br />
| A single, big endian [[wikipedia:IEEE 754-2008|IEEE-754]] single-precision floating point number<br />
|-<br />
| 6<br />
| TAG_Double<br />
| 8<br />
| A single, big endian [[wikipedia:IEEE 754-2008|IEEE-754]] double-precision floating point number<br />
|-<br />
| 7<br />
| TAG_Byte_Array<br />
| ...<br />
| A length-prefixed array of '''signed''' bytes. The prefix is a '''signed''' integer (thus 4 bytes)<br />
|-<br />
| 8<br />
| TAG_String<br />
| ...<br />
| A length-prefixed [[wikipedia:UTF-8|UTF-8]] string. The prefix is an '''unsigned''' short (thus 2 bytes)<br />
|-<br />
| 9<br />
| TAG_List<br />
| ...<br />
| A list of '''nameless''' tags, all of the same type. The list is prefixed with the <code>Type ID</code> of the items it contains (thus 1 byte), and the length of the list as a '''signed''' integer (a further 4 bytes).<br />
|-<br />
| 10<br />
| TAG_Compound<br />
| ...<br />
| Effectively a list of a '''named''' tags. Order is not guaranteed.<br />
|-<br />
| 11<br />
| TAG_Int_Array<br />
| ...<br />
| A length-prefixed array of '''signed''' integers. The prefix is a '''signed''' integer (thus 4 bytes) and indicates the number of 4 byte integers.<br />
|}<br />
<br />
<br />
There are five simple things to remember:<br />
* '''Everything''' is in big-endian in the PC version, but Pocket Version is in little-endian. Unless you're using Java, you will most likely have to swap it to little-endian. See [[wikipedia:Endianness|the Wikipedia article on Endianness]].<br />
* Every NBT file will '''always''' begin with a TAG_Compound. No exceptions.<br />
* Every tag begins with a single byte which is is the <code>Type ID</code> of the following tag.<br />
* Every tag, except TAG_End, begins with a TAG_String, minus the <code>Type ID</code>. This is the name given to whatever is stored in the tag.<br />
* The preceding two rules do '''not apply''' to the first level of tags within a <code>TAG_List</code>.<br />
<br />
For example, here's the example layout of a <code>TAG_Short</code> on disk:<br />
<br />
{| class="wikitable"<br />
|-<br />
| <br />
! Type ID<br />
! Length of Name<br />
! Name<br />
! Payload<br />
|-<br />
! Decoded<br />
| 2<br />
| 9<br />
| <code>shortTest</code><br />
| <code>32767</code><br />
|-<br />
! On Disk (in hex)<br />
| <code>02</code><br />
| <code>00 09</code><br />
| <code>73 68 6F 72 74 54 65 73 74</code><br />
| <code>7F FF</code><br />
|}<br />
<br />
If this <code>TAG_Short</code> had been in a <code>TAG_List</code>, it would have been nothing more than the payload, since the type is implied and tags within the first level of a list are nameless.<br />
<br />
=== Examples ===<br />
There are two defacto example files used for testing your implementation (<code>test.nbt</code> & <code>bigtest.nbt</code>), originally provided by Markus. The example output provided below was generated using [https://github.com/TkTech/PyNBT PyNBT]'s ''debug-nbt'' tool.<br />
<br />
==== test.nbt ====<br />
This first example is an uncompressed [[wikipedia:Hello world program|"Hello World"]] NBT example. Should you parse it correctly, you will get a structure similar to the following:<br />
<br />
<code><br />
TAG_Compound('hello world'): 1 entry<br />
{<br />
TAG_String('name'): 'Bananrama'<br />
}<br />
</code><br />
<br />
==== bigtest.nbt ====<br />
This second example is a gzip compressed test of every available tag. If your program can successfully parse this file, then you've done well. Note that the tags under ''TAG_List'' do not have a name, as mentioned above. <br />
<code><br />
TAG_Compound('Level'): 11 entries<br />
{<br />
TAG_Compound('nested compound test'): 2 entries<br />
{<br />
TAG_Compound('egg'): 2 entries<br />
{<br />
TAG_String('name'): 'Eggbert'<br />
TAG_Float('value'): 0.5<br />
}<br />
TAG_Compound('ham'): 2 entries<br />
{<br />
TAG_String('name'): 'Hampus'<br />
TAG_Float('value'): 0.75<br />
}<br />
}<br />
TAG_Int('intTest'): 2147483647<br />
TAG_Byte('byteTest'): 127<br />
TAG_String('stringTest'): 'HELLO WORLD THIS IS A TEST STRING \xc3\x85\xc3\x84\xc3\x96!'<br />
TAG_List('listTest (long)'): 5 entries<br />
{<br />
TAG_Long(None): 11<br />
TAG_Long(None): 12<br />
TAG_Long(None): 13<br />
TAG_Long(None): 14<br />
TAG_Long(None): 15<br />
}<br />
TAG_Double('doubleTest'): 0.49312871321823148<br />
TAG_Float('floatTest'): 0.49823147058486938<br />
TAG_Long('longTest'): 9223372036854775807L<br />
TAG_List('listTest (compound)'): 2 entries<br />
{<br />
TAG_Compound(None): 2 entries<br />
{<br />
TAG_Long('created-on'): 1264099775885L<br />
TAG_String('name'): 'Compound tag #0'<br />
}<br />
TAG_Compound(None): 2 entries<br />
{<br />
TAG_Long('created-on'): 1264099775885L<br />
TAG_String('name'): 'Compound tag #1'<br />
}<br />
}<br />
TAG_Byte_Array('byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))'): [1000 bytes]<br />
TAG_Short('shortTest'): 32767<br />
}<br />
</code><br />
<br />
==== servers.dat ====<br />
The ''servers.dat'' file contains a list of multiplayer servers you've added to the game. To mix things up a bit, this file will always be uncompressed. Below is an example of the structure seen in ''servers.dat''.<br />
<code><br />
TAG_Compound(<nowiki>''</nowiki>): 1 entry<br />
{<br />
TAG_List('servers'): 2 entries<br />
{<br />
TAG_Compound(None): 3 entries<br />
{<br />
TAG_Byte('hideAddress'): 0 (Don't hide the IP address)<br />
TAG_String('name'): 'Dainz1 - Creative'<br />
TAG_String('ip'): '199.167.132.229:25620'<br />
<br />
}<br />
TAG_Compound(None): 3 entries<br />
{<br />
TAG_Byte('hideAddress'): 1<br />
TAG_String('name'): 'minstarmin4'<br />
TAG_String('ip'): '76.127.122.65:25565'<br />
<br />
}<br />
}<br />
}<br />
</code><br />
<br />
==== level.dat ====<br />
This final example is of a single player ''level.dat'', which is compressed using gzip. Notice the player's inventory and general world details such as spawn position, world name, and the game seed.<br />
<code><br />
TAG_Compound(<nowiki>''</nowiki>): 1 entry<br />
{<br />
TAG_Compound('Data'): 17 entries<br />
{<br />
TAG_Byte('raining'): 0<br />
TAG_Long('RandomSeed'): 3142388825013346304L<br />
TAG_Int('SpawnX'): 0<br />
TAG_Int('SpawnZ'): 0<br />
TAG_Long('LastPlayed'): 1323133681772L<br />
TAG_Int('GameType'): 1<br />
TAG_Int('SpawnY'): 63<br />
TAG_Byte('MapFeatures'): 1<br />
TAG_Compound('Player'): 24 entries<br />
{<br />
TAG_Int('XpTotal'): 0<br />
TAG_Compound('abilities'): 4 entries<br />
{<br />
TAG_Byte('instabuild'): 1<br />
TAG_Byte('flying'): 1<br />
TAG_Byte('mayfly'): 1<br />
TAG_Byte('invulnerable'): 1<br />
}<br />
TAG_Int('XpLevel'): 0<br />
TAG_Int('Score'): 0<br />
TAG_Short('Health'): 20<br />
TAG_List('Inventory'): 13 entries<br />
{<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 0<br />
TAG_Short('id'): 24<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 1<br />
TAG_Short('id'): 25<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 2<br />
TAG_Short('id'): 326<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 3<br />
TAG_Short('id'): 29<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 10<br />
TAG_Byte('Slot'): 4<br />
TAG_Short('id'): 69<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 3<br />
TAG_Byte('Slot'): 5<br />
TAG_Short('id'): 33<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 43<br />
TAG_Byte('Slot'): 6<br />
TAG_Short('id'): 356<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 64<br />
TAG_Byte('Slot'): 7<br />
TAG_Short('id'): 331<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 20<br />
TAG_Byte('Slot'): 8<br />
TAG_Short('id'): 76<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 64<br />
TAG_Byte('Slot'): 9<br />
TAG_Short('id'): 331<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 10<br />
TAG_Short('id'): 323<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 16<br />
TAG_Byte('Slot'): 11<br />
TAG_Short('id'): 331<br />
TAG_Short('Damage'): 0<br />
}<br />
TAG_Compound(None): 4 entries<br />
{<br />
TAG_Byte('Count'): 1<br />
TAG_Byte('Slot'): 12<br />
TAG_Short('id'): 110<br />
TAG_Short('Damage'): 0<br />
}<br />
}<br />
TAG_Short('HurtTime'): 0<br />
TAG_Short('Fire'): -20<br />
TAG_Float('foodExhaustionLevel'): 0.0<br />
TAG_Float('foodSaturationLevel'): 5.0<br />
TAG_Int('foodTickTimer'): 0<br />
TAG_Short('SleepTimer'): 0<br />
TAG_Short('DeathTime'): 0<br />
TAG_List('Rotation'): 2 entries<br />
{<br />
TAG_Float(None): 1151.9342041015625<br />
TAG_Float(None): 32.249679565429688<br />
}<br />
TAG_Float('XpP'): 0.0<br />
TAG_Float('FallDistance'): 0.0<br />
TAG_Short('Air'): 300<br />
TAG_List('Motion'): 3 entries<br />
{<br />
TAG_Double(None): -2.9778325794951344e-11<br />
TAG_Double(None): -0.078400001525878907<br />
TAG_Double(None): 1.1763942772801152e-11<br />
}<br />
TAG_Int('Dimension'): 0<br />
TAG_Byte('OnGround'): 1<br />
TAG_List('Pos'): 3 entries<br />
{<br />
TAG_Double(None): 256.87499499518492<br />
TAG_Double(None): 112.62000000476837<br />
TAG_Double(None): -34.578128612797634<br />
}<br />
TAG_Byte('Sleeping'): 0<br />
TAG_Short('AttackTime'): 0<br />
TAG_Int('foodLevel'): 20<br />
}<br />
TAG_Int('thunderTime'): 2724<br />
TAG_Int('version'): 19132<br />
TAG_Int('rainTime'): 5476<br />
TAG_Long('Time'): 128763<br />
TAG_Byte('thundering'): 1<br />
TAG_Byte('hardcore'): 0<br />
TAG_Long('SizeOnDisk'): 0<br />
TAG_String('LevelName'): 'Sandstone Test World'<br />
}<br />
}<br />
</code><br />
<br />
==== Download ====<br />
* [https://raw.github.com/Dav1dde/nbd/master/test/hello_world.nbt test.nbt/hello_world.nbt] (uncompressed),<br />
* [https://raw.github.com/Dav1dde/nbd/master/test/bigtest.nbt bigtest.nbt] (gzip compressed)</div>Drainedsoulhttps://wiki.vg/index.php?title=Talk:NBT&diff=3124Talk:NBT2011-11-29T23:08:57Z<p>Drainedsoul: </p>
<hr />
<div>I find myself a bit confused regarding the TAG_String name thing. I understand that it is used to identify each tag, but the portion which confuses me is that the article implies that not all tags have this name attached to them, "Note that ONLY Named Tags carry the name and tagType data. Explicitly identified Tags (such as TAG_String above) only contains the payload."<br />
<br />
Now, my question is, what is considered a named tag, and what is not? <br />
<br />
~Thanks<br />
<br />
:"Tagged" imples: tag type, name, payload. "Untagged" implies just the payload. If you had a TAG_List of TAG_Shorts, each element of the list is *just* the short payload, i.e. 2 bytes per element. As such the children of TAG_Lists are unnamed. TAG_Lists define a "tagId" at the start of their payload so you know what kind of tag you're reading. Named tags exist only in two circumstances: 1) As children of TAG_Compound, 2) As the root node. [[User:Barneygale|Barneygale]] 17:52, 25 November 2011 (MST)<br />
<br />
:Thanks! Understood.<br />
<br />
----<br />
<br />
I have altered the bigtest.nbt example due to the fact the example readout was not correctly representing the UTF-8 encoding actually contained in the document.<br />
<br />
The string purported to be "HELLO WORLD THIS IS A TEST STRING !" but was actually "HELLO WORLD THIS IS A TEST STRING ÅÄÖ!"<br />
<br />
This can be verified by examining the bytes which make up the string:<br />
<br />
72 69 76 76 79 32 87 79 82 76 68 32 84 72 73 83 32 73 83 32 65 32 84 69 83 84 32 83 84 82 73 78 71 32 195 133 195 132 195 150 33<br />
<br />
Using a [http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder UTF-8 decoder] in "Freeflow Numeric" mode.<br />
<br />
~[[User:Drainedsoul|Drainedsoul]] 15:06, 29 November 2011 (PST)</div>Drainedsoulhttps://wiki.vg/index.php?title=Talk:NBT&diff=3123Talk:NBT2011-11-29T23:08:34Z<p>Drainedsoul: </p>
<hr />
<div>I find myself a bit confused regarding the TAG_String name thing. I understand that it is used to identify each tag, but the portion which confuses me is that the article implies that not all tags have this name attached to them, "Note that ONLY Named Tags carry the name and tagType data. Explicitly identified Tags (such as TAG_String above) only contains the payload."<br />
<br />
Now, my question is, what is considered a named tag, and what is not? <br />
<br />
~Thanks<br />
<br />
:"Tagged" imples: tag type, name, payload. "Untagged" implies just the payload. If you had a TAG_List of TAG_Shorts, each element of the list is *just* the short payload, i.e. 2 bytes per element. As such the children of TAG_Lists are unnamed. TAG_Lists define a "tagId" at the start of their payload so you know what kind of tag you're reading. Named tags exist only in two circumstances: 1) As children of TAG_Compound, 2) As the root node. [[User:Barneygale|Barneygale]] 17:52, 25 November 2011 (MST)<br />
<br />
:Thanks! Understood.<br />
<br />
----<br />
<br />
I have altered the bigtest.nbt example due to the fact the example readout was not correctly representing the UTF-8 encoding actually contained in the document.<br />
<br />
The string purported to be "HELLO WORLD THIS IS A TEST STRING !" but was actually "HELLO WORLD THIS IS A TEST STRING !"<br />
<br />
This can be verified by examining the bytes which make up the string:<br />
<br />
72 69 76 76 79 32 87 79 82 76 68 32 84 72 73 83 32 73 83 32 65 32 84 69 83 84 32 83 84 82 73 78 71 32 195 133 195 132 195 150 33<br />
<br />
Using a [http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder UTF-8 decoder] in "Freeflow Numeric" mode.<br />
<br />
~[[User:Drainedsoul|Drainedsoul]] 15:06, 29 November 2011 (PST)</div>Drainedsoulhttps://wiki.vg/index.php?title=Talk:NBT&diff=3122Talk:NBT2011-11-29T23:08:03Z<p>Drainedsoul: </p>
<hr />
<div>I find myself a bit confused regarding the TAG_String name thing. I understand that it is used to identify each tag, but the portion which confuses me is that the article implies that not all tags have this name attached to them, "Note that ONLY Named Tags carry the name and tagType data. Explicitly identified Tags (such as TAG_String above) only contains the payload."<br />
<br />
Now, my question is, what is considered a named tag, and what is not? <br />
<br />
~Thanks<br />
<br />
:"Tagged" imples: tag type, name, payload. "Untagged" implies just the payload. If you had a TAG_List of TAG_Shorts, each element of the list is *just* the short payload, i.e. 2 bytes per element. As such the children of TAG_Lists are unnamed. TAG_Lists define a "tagId" at the start of their payload so you know what kind of tag you're reading. Named tags exist only in two circumstances: 1) As children of TAG_Compound, 2) As the root node. [[User:Barneygale|Barneygale]] 17:52, 25 November 2011 (MST)<br />
<br />
:Thanks! Understood.<br />
<br />
----<br />
<br />
I have altered the bigtest.nbt example due to the fact the example readout was not correctly representing the UTF-8 encoding actually contained in the document.<br />
<br />
The string purported to be "HELLO WORLD THIS IS A TEST STRING !" but was actually "HELLO WORLD THIS IS A TEST STRING !"<br />
<br />
This can be verified by examining the bytes which make up the string:<br />
<br />
72 69 76 76 79 32 87 79 82 76 68 32 84 72 73 83 32 73 83 32 65 32 84 69 83 84 32 83 84 82 73 78 71 32 195 133 195 132 195 150 33<br />
<br />
Using a [http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder UTF-8 decoder] in "Freeflow Numeric" mode.</div>Drainedsoulhttps://wiki.vg/index.php?title=NBT&diff=2007NBT2011-11-29T23:04:12Z<p>Drainedsoul: </p>
<hr />
<div>NBT (Named Binary Tag) is a tag-based binary format designed to carry binary data accompanied by additional data.<br />
<br />
An NBT file consists of a single root TAG_Compound and is compressed with GZip.<br />
<br />
A single named tag is structured as follows:<br />
<br />
{| class="wikitable" style="margin: 1em auto 1em auto;"<br />
! scope="col" | Tag Type<br />
! scope="col" | Name Length<br />
! scope="col" | Name<br />
! scope="col" | Payload<br />
|-<br />
| 1 byte || 2 bytes, 16 bit integer, signed, big endian || UTF-8 Encoded String || Depends on type of tag<br />
|}<br />
<br />
There are 10 different types of tags:<br />
<br />
{| class="wikitable" style="margin: 1em auto 1em auto;"<br />
! scope="col" | Tag Type Value<br />
! scope="col" | Name<br />
! scope="col" | Description<br />
! scope="col" | Comments<br />
|-<br />
| 0 || TAG_End || Marks the end of a TAG_Compound. || This tag occurs to end a previously opened TAG_Compound. This tag has no name, and no payload.<br />
|-<br />
| 1 || TAG_Byte || Payload is a single signed byte (8 bits). || <br />
|-<br />
| 2 || TAG_Short || Payload is a signed 16 bit integer (big endian). ||<br />
|-<br />
| 3 || TAG_Int || Payload is a signed 32 bit integer (big endian). ||<br />
|-<br />
| 4 || TAG_Long || Payload is a singed 64 bit integer (big endian). ||<br />
|-<br />
| 5 || TAG_Float || Payload is a 32 bit floating point value (big endian, IEEE 754) ||<br />
|-<br />
| 6 || TAG_Double || Payload is a 64 bit floating point value (big endian, IEEE 754) ||<br />
|-<br />
| 7 || TAG_Byte_Array || An array of bytes. || Payload consists of four bytes which form a signed 32 bit integer (big endian) which specifies the length of the remainder of the payload.<br />
|-<br />
| 8 || TAG_String || A string. || Payload consists of two bytes which form a signed 16 bit integer (big endian) which specifies the length of the remainder of the payload. The remainder of the payload is a UTF-8 encoded string.<br />
|-<br />
| 9 || TAG_List || A list of tags. || Payload consists of one byte which specifies the type of tags found in the list, followed by four bytes which form a signed 32 bit integer (big endian) which specifies the number of tags which form the remainder of the payload. Tags in the list do not specify their type (i.e. they're missing the first byte) and do not have a name (i.e. they do not have two bytes for the length of their name, nor the bytes which makes up the name).<br />
|-<br />
| 10 || TAG_Compound || The root of nested tags. || Payload consists of sequential named tags. This sequence of named tags ends when a TAG_End is encountered. Note that TAG_Compounds can be nested within themselves, so the next TAG_End is not necessarily the end of this TAG_Compound. Recursion advised.<br />
|}<br />
<br />
----<br />
<br />
Note that none of the examples below are GZip'd<br />
<br />
----<br />
<br />
Decoding example: http://mc.kev009.com/nbt/test.nbt<br />
<br />
The first byte of this file is 10. This means that the first tag is a TAG_Compound (which is to be expected).<br />
<br />
We read two more bytes to get the length of the name of this tag. The next two bytes are 0 and 11, meaning the name is 11 bytes long. On a little endian system be sure to reverse them before creating a 16 bit signed integer with them.<br />
<br />
We read the next 11 bytes and decode them as per UTF-8. The resulting string is "hello world".<br />
<br />
Next we move onto the payload, which, since this is a TAG_Compound, is going to be more tags until we reach the TAG_End which corresponds to our TAG_Compound.<br />
<br />
Therefore, we read the next byte to determine the type of the first tag in the TAG_Compound. The next byte is an 8 -- TAG_String.<br />
<br />
The next two bytes tell us that the length of the name of this string is 4, and the next 4 bytes UTF-8 decode into "name".<br />
<br />
Next we read two more bytes to find the name of the string which is the payload of this tag, these two bytes are 0 and 9. The next 9 bytes UTF-8 decode into "Bananrama".<br />
<br />
We read the next byte to get the type of the next named tag, and find that it is 0 -- TAG_End.<br />
<br />
Therefore, we are done.<br />
<br />
The result:<br />
<br />
TAG_Compound("hello world"): 1 entries<br />
{<br />
TAG_String("name"): Bananrama<br />
}<br />
<br />
For a slightly longer test, use http://mc.kev009.com/nbt/bigtest.nbt<br />
<br />
You should end up with this:<br />
<br />
TAG_Compound("Level"): 11 entries<br />
{<br />
TAG_Short("shortTest"): 32767<br />
TAG_Long("longTest"): 9223372036854775807<br />
TAG_Float("floatTest"): 0.49823147<br />
TAG_String("stringTest"): HELLO WORLD THIS IS A TEST STRING ÅÄÖ!<br />
TAG_Int("intTest"): 2147483647<br />
TAG_Compound("nested compound test"): 2 entries<br />
{<br />
TAG_Compound("ham"): 2 entries<br />
{<br />
TAG_String("name"): Hampus<br />
TAG_Float("value"): 0.75<br />
}<br />
TAG_Compound("egg"): 2 entries<br />
{<br />
TAG_String("name"): Eggbert<br />
TAG_Float("value"): 0.5<br />
}<br />
}<br />
TAG_List("listTest (long)"): 5 entries of type TAG_Long<br />
{<br />
TAG_Long: 11<br />
TAG_Long: 12<br />
TAG_Long: 13<br />
TAG_Long: 14<br />
TAG_Long: 15<br />
}<br />
TAG_Byte("byteTest"): 127<br />
TAG_List("listTest (compound)"): 2 entries of type TAG_Compound<br />
{<br />
TAG_Compound: 2 entries<br />
{<br />
TAG_String("name"): Compound tag #0<br />
TAG_Long("created-on"): 1264099775885<br />
}<br />
TAG_Compound: 2 entries<br />
{<br />
TAG_String("name"): Compound tag #1<br />
TAG_Long("created-on"): 1264099775885<br />
}<br />
}<br />
TAG_Byte_Array("byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))"): [1000 bytes]<br />
TAG_Double("doubleTest"): 0.4931287132182315<br />
}<br />
<br />
[[Category:Minecraft Beta]]<br />
[[Category:Minecraft Classic]]<br />
[[Category:File Formats]]</div>Drainedsoulhttps://wiki.vg/index.php?title=NBT&diff=2006NBT2011-11-29T22:48:26Z<p>Drainedsoul: </p>
<hr />
<div>NBT (Named Binary Tag) is a tag-based binary format designed to carry binary data accompanied by additional data.<br />
<br />
An NBT file consists of a single root TAG_Compound and is compressed with GZip.<br />
<br />
A single named tag is structured as follows:<br />
<br />
{| class="wikitable" style="margin: 1em auto 1em auto;"<br />
! scope="col" | Tag Type<br />
! scope="col" | Name Length<br />
! scope="col" | Name<br />
! scope="col" | Payload<br />
|-<br />
| 1 byte || 2 bytes, 16 bit integer, signed, big endian || UTF-8 Encoded String || Depends on type of tag<br />
|}<br />
<br />
There are 10 different types of tags:<br />
<br />
{| class="wikitable" style="margin: 1em auto 1em auto;"<br />
! scope="col" | Tag Type Value<br />
! scope="col" | Name<br />
! scope="col" | Description<br />
! scope="col" | Comments<br />
|-<br />
| 0 || TAG_End || Marks the end of a TAG_Compound. || This tag occurs to end a previously opened TAG_Compound. This tag has no name, and no payload.<br />
|-<br />
| 1 || TAG_Byte || Payload is a single signed byte (8 bits). || <br />
|-<br />
| 2 || TAG_Short || Payload is a signed 16 bit integer (big endian). ||<br />
|-<br />
| 3 || TAG_Int || Payload is a signed 32 bit integer (big endian). ||<br />
|-<br />
| 4 || TAG_Long || Payload is a singed 64 bit integer (big endian). ||<br />
|-<br />
| 5 || TAG_Float || Payload is a 32 bit floating point value (big endian, IEEE 754) ||<br />
|-<br />
| 6 || TAG_Double || Payload is a 64 bit floating point value (big endian, IEEE 754) ||<br />
|-<br />
| 7 || TAG_Byte_Array || An array of bytes. || Payload consists of four bytes which form a signed 32 bit integer (big endian) which specifies the length of the remainder of the payload.<br />
|-<br />
| 8 || TAG_String || A string. || Payload consists of two bytes which form a signed 16 bit integer (big endian) which specifies the length of the remainder of the payload. The remainder of the payload is a UTF-8 encoded string.<br />
|-<br />
| 9 || TAG_List || A list of tags. || Payload consists of one byte which specifies the type of tags found in the list, followed by four bytes which form a signed 32 bit integer (big endian) which specifies the number of tags which form the remainder of the payload. Tags in the list do not specify their type (i.e. they're missing the first byte) and do not have a name (i.e. they do not have two bytes for the length of their name, nor the bytes which makes up the name).<br />
|-<br />
| 10 || TAG_Compound || The root of nested tags. || Payload consists of sequential named tags. This sequence of named tags ends when a TAG_End is encountered. Note that TAG_Compounds can be nested within themselves, so the next TAG_End is not necessarily the end of this TAG_Compound. Recursion advised.<br />
|}<br />
<br />
----<br />
<br />
Note that none of the examples below are GZip'd<br />
<br />
----<br />
<br />
Decoding example: http://mc.kev009.com/nbt/test.nbt<br />
<br />
The first byte of this file is 10. This means that the first tag is a TAG_Compound (which is to be expected).<br />
<br />
We read two more bytes to get the length of the name of this tag. The next two bytes are 0 and 11, meaning the name is 11 bytes long. On a little endian system be sure to reverse them before creating a 16 bit signed integer with them.<br />
<br />
We read the next 11 bytes and decode them as per UTF-8. The resulting string is "hello world".<br />
<br />
Next we move onto the payload, which, since this is a TAG_Compound, is going to be more tags until we reach the TAG_End which corresponds to our TAG_Compound.<br />
<br />
Therefore, we read the next byte to determine the type of the first tag in the TAG_Compound. The next byte is an 8 -- TAG_String.<br />
<br />
The next two bytes tell us that the length of the name of this string is 4, and the next 4 bytes UTF-8 decode into "name".<br />
<br />
Next we read two more bytes to find the name of the string which is the payload of this tag, these two bytes are 0 and 9. The next 9 bytes UTF-8 decode into "Bananrama".<br />
<br />
We read the next byte to get the type of the next named tag, and find that it is 0 -- TAG_End.<br />
<br />
Therefore, we are done.<br />
<br />
The result:<br />
<br />
TAG_Compound("hello world"): 1 entries<br />
{<br />
TAG_String("name"): Bananrama<br />
}<br />
<br />
For a slightly longer test, use http://mc.kev009.com/nbt/bigtest.nbt<br />
<br />
You should end up with this:<br />
<br />
TAG_Compound("Level"): 11 entries<br />
{<br />
TAG_Short("shortTest"): 32767<br />
TAG_Long("longTest"): 9223372036854775807<br />
TAG_Float("floatTest"): 0.49823147<br />
TAG_String("stringTest"): HELLO WORLD THIS IS A TEST STRING !<br />
TAG_Int("intTest"): 2147483647<br />
TAG_Compound("nested compound test"): 2 entries<br />
{<br />
TAG_Compound("ham"): 2 entries<br />
{<br />
TAG_String("name"): Hampus<br />
TAG_Float("value"): 0.75<br />
}<br />
TAG_Compound("egg"): 2 entries<br />
{<br />
TAG_String("name"): Eggbert<br />
TAG_Float("value"): 0.5<br />
}<br />
}<br />
TAG_List("listTest (long)"): 5 entries of type TAG_Long<br />
{<br />
TAG_Long: 11<br />
TAG_Long: 12<br />
TAG_Long: 13<br />
TAG_Long: 14<br />
TAG_Long: 15<br />
}<br />
TAG_Byte("byteTest"): 127<br />
TAG_List("listTest (compound)"): 2 entries of type TAG_Compound<br />
{<br />
TAG_Compound: 2 entries<br />
{<br />
TAG_String("name"): Compound tag #0<br />
TAG_Long("created-on"): 1264099775885<br />
}<br />
TAG_Compound: 2 entries<br />
{<br />
TAG_String("name"): Compound tag #1<br />
TAG_Long("created-on"): 1264099775885<br />
}<br />
}<br />
TAG_Byte_Array("byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))"): [1000 bytes]<br />
TAG_Double("doubleTest"): 0.4931287132182315<br />
}<br />
<br />
[[Category:Minecraft Beta]]<br />
[[Category:Minecraft Classic]]<br />
[[Category:File Formats]]</div>Drainedsoul