Talk:Protocol

From wiki.vg
Revision as of 19:39, 26 May 2011 by Sadimusi (talk | contribs) (→‎Block Action? (0x3D))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Too Large?

MediaWiki gave me a warning about this page being too large for some browsers. Perhaps it should be split in half? --SpaceManiac 00:44, 6 November 2010 (EDT)

Player Position (0x0B) really absolute position?

As of version 1.2.0_02, I was watching the packets my server software was receiving while walking around, and the xyz coordinates of packet type 0x0b appear to correlate 1:1 with where a player is in block coordinates, not pixel coordinates. Yen

Absolute position position is specified as block coordinates, It appears this has changed before the move, I put in these definitions originally to clarify such things, absolute double's should be block coordinates, with the fraction being the offset in the block. ReDucTor

So "Absolute" is in meters, but "Absolute integer" is in pixels? Can't we come up with better names? I propose we name coordinates by the size of 1 unit. We change the names like this: Absolute -> meters; Absolute integer -> pixels; Block -> meters; Chunk -> chunks. Currently, the only two "units of measurement" with the same name are in fact different units of measurement. The focus of the current names seems to be the precision of the types, which seems less important to convey to readers than the scale of each unit relative to one another. --Thejoshwolfe 22:55, 25 January 2011 (MST)

New Server Packet 0x1c

The 11/10/2010 update has a new server to client packet (0x1c) 11 bytes long, the first field appears to be an EID. The packet is sent when a pickup is spawned in the world, either by throwing something, or mining. If the packet is ignored, the pickups never appear on the client. Jorgon3d 20:34, 10 November 2010 (EST)

New Client Packet 0x15

The 11/10/2010 update has a new client to server packet (0x15). It appears to be exactly as the Server to Client packet "Pickup Spawn". Jorgon3d 20:34, 10 November 2010 (EST)

Version 4

I've added the new packets from Version 4, and what I believe they match with, if people could please match these with what they see. And a Grammar Nazi fix up my failures. Please join irc.esper.net / #mcc to discuss this new protocol. ReDucTor

C->S Block change with direction=-1

(Client to server) It appears now after a block change is sent there is another block change that follows this with all values -1 except block id of the change, from what I can determine this causes the players selected inventory to be changed if needed from this block change. Anyone looked into this? ReDucTor

New packets introduced in SMP Health update

Looking at the new server JAR I've seen three new packets. IDs are 0x08(<byte>), 0x09(), and 0x26(<int>,<byte>).

0x08 I'm thinking could be the players health update packet, 0x26 perhaps the 'hit entity' packet, 0x09 I'm not sure.

I'll confirm what these packets do tonight when I get back from work.

The 0x09 packet is for respawning. It is sent in both directions for when the player should respawn. 0x08 is the health, yes. Haven't gotten to 0x26 yet. Blixt 08:17, 24 November 2010 (EST)
Packet 0x07 from client to server has a new field of 1 byte. Its value is usually 1 which would make your client try to read a 0x01 packet, which includes a string, so that explains why you're getting errors about negative lengths, unicode or simply if the client stops reading more data. Blixt 10:01, 24 November 2010 (EST)
I believe I found a VERY subtle change that caused my client to crash when proxied through a wrapper that reads and writes packets: The packet for animating (0x12) now supports values other than 0 and 1 (bool): I got 2 for some packets. Blixt 10:14, 24 November 2010 (EST)
The 0x07 packet has a new bool for attacking_animal. It is 0 when using things vs air or blocks, and 1 when used on zombies, animals, and probably players (haven't tested yet). benmanns 10:24, 24 November 2010 (EST)
0x07 is never sent when you hit normal blocks or air. It's for interacting with an entity (thus it also has an entity id). I do get true whenever I hit a mob though, so that part seems correct. Blixt 10:59, 24 November 2010 (EST)
0x26 appears to be sent when an entity dies. The last byte seems to be 3 most of the time. No idea what that means. My wrapper (http://github.com/blixt/pyminecraft) is working fine now, but there seems to be a few bugs relating to burning mobs... don't know why. Blixt 10:59, 24 November 2010 (EST)
Never mind, I was forcing the client to think it was day, so during the night (on the server) the client thought the monsters should burn so they started burning, then the server said they weren't burning so they stopped burning. :) Blixt 14:15, 24 November 2010 (EST)

Complex entity packet (0x3B) client->server

Is this new? Wasn't it only server->client before? The client is sending 0x3B to the server whenever you put stuff in a chest now, anyways. Blixt 11:37, 29 November 2010 (EST)

Nov 30 update

Today's update seems to change the following:

  • The 0x26 packet now sends values other than 3 for the byte field. The value 2 means an entity was hurt. The value 3 means an entity died. The value 4 is sent the moment a creeper starts flashing.
  • There is a new packet 0x3C. I haven't investigated this yet but my guess is it's got to do with sound. It appears to be sent when a creeper is about to explode.
  • There are a lot of new values for packet 0x12 (animate), such as 104 for crouching, 105 for standing up.

- Blixt 17:58, 30 November 2010 (EST)

Has anyone looked into this? I am starting to suspect that 0x3C is a packet specific to explosions... It seems to have a structure similar to 0x34 / Multi Block Change. – Blixt 05:12, 1 December 2010 (EST)
The packet structure is like this: double, double, double, float, n = integer, n * 3 bytes. The first three doubles correspond well with X, Y, Z. The float is currently unknown. It was 3.0 for me, might be a radius or something. The list of bytes appears to be a bunch of block offsets, presumably the blocks that were destroyed in the explosion. The range of the values seems to be a bit strange though, I got the X offset as -6 up to 3, which means the explosion wouldn't be centered on the X, Y, Z coordinates. Also, the list seems to include air blocks, which seems a bit unnecessary. More investigation needed. – Blixt 18:04, 1 December 2010 (EST)

Map chunks vs. mini chunks

I'd like to make a distinction between "mini chunks" and "map chunks". Mini chunks are updates that have the same purpose as "multi block updates". The X/Y/Z size and position can be anything. Map chunks are complete 16x128x16 pieces of the map. Mini-chunk updates can arrive before map chunk updates.

"Prechunk" packet marks where a map chunk will be visible to the client, eventually. It can come well before the client should draw, though. My client will only draw a map chunk that has had a full 16x128x16 chunk update (loaded), and a prechunk packet (visible). Mini-chunks might come before prechunks, and prechunks usually come before map chunks, but both sides have to be flexible. I *have* seen mini-chunks cross map chunk boundaries, but it might be a bug in my client ;p

Example: 6x4x5 mini-chunk sent for [-1022, 20, 50]. Prechunk sent for [-1024/16, 48/16]. 16x128x16 map chunk sent for [-1024, 0, 48], overwriting the mini-chunk. Now it's drawn, because client has prechunk and full map chunk. Remember, chunk sizes are encoded as size-1.

Currently unlisted packets.

Some packets are listed as only going in one direction, but are actually sent the other too. To my knowledge, these are:

  • S->C 0x0a
  • S->C 0x0b
  • C->S 0x3b (mentioned above)

The packets are identical to their counterparts. Barneygale 17:02, 15 December 2010 (EST)


Were you connecting to a standard server? I've only received 0xa and 0xb from unofficial servers. --Axus 13:21, 16 December 2010 (EST)

beta update December 20, 2010

Someone pasted some notes about the protocol changes here: http://pastebin.com/YfR9XgC2

Question: Does 0x0D Player Position and Look Client->Server still differ from Server->Client?

I haven't seen any differences in how player position works. I've updated my wrapper and server to work with the new protocol and everything seems fine. See this diff for most packet changes: https://github.com/blixt/pyminecraft/commit/af4c9f6b9b2387e429fa425dd5061ef01e03c5aa#diff-1Blixt 10:30, 21 December 2010 (EST)
I updated the packets that were missing information, and changed the notion from "inventories" to "windows" as that makes more sense. I also believe that's the term used by Notch when he mentioned his implementation in some blog post. - Blixt 19:25, 21 December 2010 (EST)
Sorry, the term he used was "popup", not "window". But still, the way the packets work is popup/window-centric, not inventory/container-centric (since every time a popup/window is opened, it gets a new id, the ids are not specific to which container/inventory is opened - except for the player inventory of course). - Blixt 07:18, 22 December 2010 (EST)

Note! As of 1.1, the Transaction packet goes in both direction (previously it was only sent by the server). - Blixt 09:56, 22 December 2010 (EST)

Why the merge?

I noticed the client/server and server/client sections were merged - why was this? It makes it difficult to tell the difference between packet directions when they're unidirectional. --SpaceManiac 13:31, 21 December 2010 (EST)

I don't mind the merge so much (the page is quite a bit shorter), but we should have a list or table of C<->S mapping. Having quick access to that makes writing an inbound {client, server} decoder much easier. --kev009

Actually, a merge makes sense, since the original Minecraft server itself does not differ between directions when defining its packets (that's why there are two unused fields in each direction for the handshake packet, for example). But yes, a notion on which direction(s) a packet can be sent would make sense, possibly with a simple table for each direction at the top for a quick reference on all packets for one direction. - Blixt 19:23, 21 December 2010 (EST)

Y/Stance

Two things.. The "Y" and "Stance" are, for Client->Server at least, in the same order in both 0B and 0D packets. Perhaps the discrepancy has been fixed in a recent protocol version, but I haven't checked Server->Client yet.

Also the F3 Coordinate display in Minecraft shows, for Y, what we are calling "Stance" on the page. The server uses "stance" to mean neither coordinate, but in fact the difference between the two, ie, the height of the player. This would make more sense as something to be called "stance" too.

So, I would say the upper of the two coordinates (currently called "stance") should be called "Y", and the lower (currently called "Y") should be "foot height" or something like that. Neither should be called "stance". Moo 10:15, 1 January 2011 (MST)


I like having "Y" correspond to player's foot position. What happens if player is standing at Y=127? Eye height becomes 128.62, which maps out of the normal chunk coordinates. Items and monsters give Y at their foot position, doing the same with players would be consistent. --Axus 07:16, 3 January 2011 (MST)


"What happens if player is standing at Y=127? Eye height becomes 128.62," Minecraft itself shows the player's Y coordinate as 129.62 when as high as can currently be reached. Monsters and items don't have a camera/eye position to account for, so that would probably explain why they use the "foot position". Moo 16:15, 6 January 2011 (MST)
I agree with Axus that "Y" should be the foot position to be consistent with mobs and such. But "Stance" is really the wrong name for the field in the Player Position messages. Like Moo said, the server calls "stance" the difference between the eyes and feet. The fields in the Player Position messages should be "Y" and "Eye Y". Note that Eye Y is NOT the top of the player's bounding box. Players are 1.74 meters tall, and foot-to-eye distance only goes up to 1.65 meters. Also changing your Eye Y does not make you appear to crouch according to my experiments. --Thejoshwolfe 04:35, 9 February 2011 (MST)

Connection "hash" somewhat misleading?

I know some guys who are writing server software for Minecraft, and I know one thing they were confused about was how to generate the connection "hash". Was it an MD5 hash or a SHA1 hash or what? I looked into it for them and discovered that it wasn't actually what we considered a hash at all. Instead, it was a random long in hexadecimal form. Literally. Take a look at this code:

public void a(h paramh) {

 if (this.e.l) {
   this.i = Long.toHexString(d.nextLong());
   this.b.a(new h(this.i));
 } else {
   this.b.a(new h("-"));
 }

}

h turns out to be the handshake packet class. this.b.a() appears to send the client a packet, and this.d (referred to as just d) is a Random object. this.e.l is the variable in the MinecraftServer object that tells whether 'online-mode' is on or off. All I'm asking is for there to be a little clarification on what exactly the connection "hash" is, as not everyone can go trudging through obfuscated code to find how it's generated. Is it alright for me to do this? AnonymousJohn 21:21, 9 January 2011 (MST)

Beta 1.2 Update

Lots of "interesting" things.

The most "interesting" is what looks like "Custom mob data" at the end of Mob Spawn 0x18 and new packet 0x28 (Mob Update?). The "Custom mob data" is a byte stream with each data type encoded in a byte. According to pastebin:

The "metadata" byte is split this way:

  • j: First 3 bits, data type
  • k: Last 5 bits, data key

"j" data type:

  • 0: byte
  • 1: short
  • 2: int
  • 3: float
  • 4: string (short, bytes)
  • 5: inventory item (short, byte, short)

After the "metadata" byte is data of the "data type".

Example:

  • 0x00, 0x00, 0x7F:
    • j = 0, k = 0. Key = 0, byte value = 0x00.
    • End of stream marked by 0x7F.
  • 0x00, 0x00, 0x10, 0xFF, 0x7F:
    • j = 0, k = 0. Key = 0, byte value = 0x00.
    • j = 0, k = 16. Key = 16, byte value = 255.
    • End of stream marked by 0x7F.

Packet ID datatype explanation

The page needs to mention what datatype the packet ID is. My experimentation has revealed it to be unsigned char, however I'm not sure whether this is correct, and if so, where it should appear on the page. --ElectronicsRules 04:40, 17 January 2011 (MST)

OK I added something. --Axus 05:24, 17 January 2011 (MST)

Signed/Unsigned Byte Values

Section #SizeX.2C_SizeY.2C_SizeZ in the Map Chunk section says that bytes can be values up to 255. There needs to be clarification when bytes are signed and when they're unsigned. Java's bytes are always signed. --Thejoshwolfe 20:31, 23 January 2011 (MST)

Absolute integer relation to absolute position

The formula is currently stated as:

absolute_int = (int)(absolute_double / 32.0);

But in my understanding it should be:

absolute_int = (int)(absolute_double * 32.0);


I think you're correct. You have to divide "absolute int" by 32 to get the block position, and "absolute double" is block position with extra precision --Axus 08:44, 30 January 2011 (MST)

Oops. Good catch. Thanks. --Thejoshwolfe 16:19, 30 January 2011 (MST)

Packet 0xA

I've removed the note about this packet being used for speedhacking detection as it doesn't really make sense considering it is a client-to-server packet. The client is authoritative on movement of the player. Note that the "Player moved wrongly" server console warning is based on movement delta thresholds and not ground/airborne state, which seems to be used exclusively for fall damage application (try forcing the "on ground" state to be True in all c>s player movement packets) --Entity 06:05, 5 February 2011 (MST)

Forcing 'on ground' state to be True on all c->s movement does indeed eliminate fall damage. However, when 'on ground' is forced True, you cannot ride minecarts - I haven't tested this yet for boats. Coldelectrons 09:00, 1 May 2011 (MST)

big endian conversion c++

converting integer types from big endian to little endian and vice versa is rather simple

when using visual studio this might need some adjusting thou please make sure you understand this and reimplement it to fit your needs, this is basically just pseudo code that could be compiled with a c++ compiler

#include <endian.h>

int32_t toInt(char* somedata)
{
  int32_t result = *((int32_t*)somedata);
  result = be32toh(result);
  return result;
}

//for doubles and floats you need some more pointer magic (I know it's evil)

float toFloat(char* somedata)
{
  int32_t result = *((int32_t*)somedata);
  float* result_pointer = & result;
  result = be32toh(result);
  return *result_pointer;
}

--Ker 14:53, 17 February 2011 (MST)

Wolves metadata

I'm handling metadata as explained here http://mc.kev009.com/Protocol#Metadata When i do byte y = x >> 5; i keep getting -4 for wolves. New type of metadata, or is it just my fault? --Ligustah 04:18, 1 April 2011 (MST)

Not necessarily wrong, X might really be 0xFFC?????, which would make Y look like "-4". Need to be checked of course. --Axus 08:03, 2 April 2011 (MST)

I did a little more testing: https://gist.github.com/900428 I added metadata packets that i received in different situations. --Ligustah 06:35, 3 April 2011 (MST)

The -4 mentioned earlier was actually my bad. I was using a byte to hold my x while it should have been an unsigned byte. I also updated the paste above and added all indices i observed with this packet. --Ligustah 08:16, 3 April 2011 (MST)

Version 11 (Beta 1.5)

Changes I've noticed so far:

All strings in packets are now 2-byte Big-Endian Unicode. The string length prefix value specifies #of chars not bytes;

Packet 0x64 appears all different. String remains Modified-UTF. That's a big consistency WTF.

Packet 0x66 gained a byte between Action and Item ID

Login 0x01 response from server now appears EID (int) followed by 11 bytes (in my case); Looks like short,string,long,byte and that the second string was dropped. Total packet len 16 + (2 * strSize).

Weather Event Packet 0x47 (71). (int, byte, int, int, int)
So far this packet has only shown itself for a lightning strike. The value of the byte was then always 1. During all other events (rain start/stop) this packet was nowhere to be seen whether during gameplay or when logging to SMP during a rainstorm. The first int appears to be an Entity ID as it always grew with every new strike. Last 3 ints were the X,Y,Z coords respectively of the strike on the ground. It appears to be only S->C --xiix 11:19, 20 April 2011 (MST)

Packet 0x46 was also updated. The packet is the ba class. I grepped for "new ba" and got 3 hits

The first 2 are in the dg class. These extends the da class which has code that seems to slowly change the raining state.

protected void i()
{
   boolean bool = v();
   super.i();
   
   if (bool != v())
     if (bool)
       this.z.f.a(new ba(2));
     else
       this.z.f.a(new ba(1));
}

The call to v() checks if it is still raining and the call to i() updates the raining counter.

This basically says that if the rain state changes, send a 0x46 packet.

1 = begin raining

2 = end raining

The next hit is in the du class.

 if (this.e.e.v()) {
   localgj.b(new ba(1));
 }

this.e is the MinecraftServer and this.e.e is of type dg. This says that if it is raining, then send a packet with code 1. This method seems to be for logging in.

The final hit is in the ep class.

   if (localaq2 != null) {
     localdc.c(localaq2.a + 0.5F, localaq2.b + 0.1F, localaq2.c + 0.5F, 0.0F, 0.0F);
     localdc.a(localaq1);
   } else {
     localdc.a.b(new ba(0));
   }

The is probably the bed case.

So, anyway, the possible values would be:

Code Effect
0 Invalid Bed
1 Begin raining
2 End raining

Tested and confirmed --xiix 15:30, 23 April 2011 (MST)

The reason byte is a public variable, so it is possible that the code is set from other places. However, since the string array only has 3 values, that suggests that these are the 3 valid values.

Btw, what is the policy on editing the main protocol page itself? --Raphfrk 13:57, 23 April 2011 (MST)

Mystery packet 0xC8 (200). Follows hitting entities (cows and whatnot) or destroying/placing anything else:

  • bool : 0 entity destroyed; 1 otherwise, even if block is dug out it still exists so maybe that's why this one's always 1;
  • byte : 0 entity/block destroyed; 2 block or item placed;
  • byte : ???;
  • byte : block/item ID; for entities no clue;
  • byte : for bool=0 changes depending on what you hold, hit strength maybe;

Sent only Server->Client.

--xiix 18:20, 19 April 2011 (MST)

/* Item data type */

In my own code, I've simplified things by treating the 3 items (short, optional byte,short) as an Item. It makes my packet format definitions far more readable.

Any votes in favor of applying the Item definition to the existing page?

Size Range Notes
Item 2-5 N/A The structure is (short ItemID, [byte Count, short MetaDamage]). If ItemID == -1, the latter two items are omitted.

-- Coldelectrons

Would have been fine but 0x05 does not comply with this. Personally I'd rather deal with no rules than rules that have exceptions to them. --xiix 09:43, 20 April 2011 (MST)

0x01 Login C->S (Version 11)

Since I'm a n00b here I won't edit the wiki itself for the fear of being an idiot, but to whoever did: from my own packet analysis the 'Client->Server' login 0x01 packet remains unchanged except for the String8->String16 mod. Either Password (or other text) is still possibly sent (now empty) or it has 2 extra (0,0) bytes for whatever reason after username. So the makeup for my money is int, string16, string16, long, sbyte. The length of the packet remains 18 + len of string16's.

Also, re new String16 thing. Maybe this is common knowledge for java folk, but for us MS/.NET dweebs it is important to know that the new string16 is actually UTF-16BE, as UTF-16 (implies UTF-16LE) decode will render gibberish.

--xiix 09:38, 20 April 2011 (MST)

Note that it's actually big-endian UCS-2. Treating it as UTF-16 will likely work most of the time, except for crafted packets or otherwise misbehaving peers.

--Huin 14:22, 15 May 2011 (MST)

/* Byte-packed double? */

The 3 ints int the weather packet: Can someone please explain or link to an explanation of how it is you pack a double-precision floating point (8 bytes) number into an int (4 bytes)? Bonus points for why you would want to do it that way?

I might be wrong but I don't think it is a packed double in a true packing sense. What you do is in this instance is:

double = int / 32.0 --xiix 08:26, 21 April 2011 (MST)

0x32 (pre-chunk) packet optional?

I've tried sending 0x33 packets without 0x32 packets to a 1.5 Beta client on initial connection - the client simply doesn't like it, and just jiggles up and down and the chunks are not visible.

Sending the same 0x33 packets with 0x32 packets following results in the client falling, but the chunks being completely air-blocks.

The chunks only appear to load correctly if each 0x33 packet is preceded by the corresponding 0x32 packet (even if not immediately preceding).

Any other observations on this matter? It appears to me that the 0x32 packet to initialize the chunk is always required, rather than optional as the current text about packet 0x33 might suggest.

--Huin 14:19, 15 May 2011 (MST)

It might only matter on chunks close to the player. I think the "optional" note was more for client writers to allow strange exceptions from Notch's server, than for letting server writers take it easy ;) --Axus 16:03, 16 May 2011 (MST)

Perhaps the times when the notchian server *doesn't* send the 0x32 is when the 0x33 packet is for a subset of the chunk (that is: an already loaded chunk). It would be nice to back this up with evidence of course. --Huin 14:24, 21 May 2011 (MST)

0x18 - Where does the 'Index' come from? + Metadata String

Can somebody tell me where the index come from? Is this a byte in the metastream or what ?

Additionally there is no information about the width of the string chars in a metastream.

--Chrisliebaer 11:39, 22 May 2011 (MST)

0x47 - Weather?

22 May 2011 - Just started writing a library to read and write packets. Tried to follow the spec for 0x47 on the page, and kept getting errors. Looked at a Wireshark capture, and I see the 0x47 packet as being 8 bytes long (9 with the header). The first four bytes look to be an int related to location? It was negative in my capture. The next three bytes were all 0's, then a 0x02. --User:Nyasara

Map data (0x83)

It seems like there is a new packet 0x83 which I can't figure out. Decompiling it reveals four possible forms: http://pastie.org/1975651 --Sadimusi 04:10, 26 May 2011 (MST)

I wonder if it handles something related to Nether travel (probably reaching).

I guess the respawn packet with the new field might be all that was added for handling this.

Does the Nether have any use for a new world seed? If not, then I guess adding the Nether didn't require that a "change world seed" packet was created. If so, that is pretty disappointing. This would have been a perfect time to add a way to update the client's world seed.

I am going to run a test tonight to see if the client can handle a second login packet after the update.

--Raphfrk 05:12, 26 May 2011 (MST)

Block Action? (0x3D)

This packet is

Int Int Byte Int Int

It seems to be related to opening doors

Int: 1003 (constant) Int: X position of door Byte: Y position of door Int: Z position of door Int: 0 (constant)

The packet is sent to all players except the player who opens the door. --Raphfrk 11:56, 26 May 2011 (MST)

It is also sent to all near players when a door is opened with a redstone current. --Sadimusi 12:39, 26 May 2011 (MST)