New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1.12.2 protocol support (340) #40
Conversation
CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData
parsing packet id 3c direction Clientbound in state Play pub const EntityMetadata: i32 = 0x3c; src/types/metadata.rs _ => return Err(protocol::Error::Err("unknown metadata type".to_owned())), https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format New metadata type is 13, which is "NBT Tag" https://wiki.vg/NBT |
Gets to the terrain: but crashes shortly after, some encoding error: parsing packet id 3c direction Clientbound in state Play 7: steven::server::Server::entity_tick Err(err) => panic!("Err: {:?}", err), Packet handling in entity_tick(). An error returned from rx.try_recv()? entity_tick pck = Ok(EntityLookAndMove(EntityLookAndMove { entity_id: 1573, delta_x: -1078, delta_y: -636, delta_z: 317, yaw: 52, pitch: 0, on_ground: false })) The error is definitely from nbt::Tag::read_from(buf): match nbt::Tag::read_from(buf) {
Ok(nbt) => m.put_raw(index, nbt),
Err(err) => println!("Metadata NBT tag parsing error: {:?}", err),
} Metadata NBT tag parsing error: IOError(Custom { kind: InvalidData, error: StringError("stream did not contain valid UTF-8") }) src/nbt/mod.rs: pub fn read_string<R: io::Read>(buf: &mut R) -> Result<String, protocol::Error> {
let len: i16 = buf.read_i16::<BigEndian>()?;
let mut ret = String::new();
buf.take(len as u64).read_to_string(&mut ret)?;
Result::Ok(ret)
} https://doc.rust-lang.org/nightly/std/io/trait.Read.html#method.read_to_string
|
i16 is 3338 (0x0d0a), reading into a Vec with read_to_end instead of read_to_string: pub fn read_string<R: io::Read>(buf: &mut R) -> Result<String, protocol::Error> {
let len: i16 = buf.read_i16::<BigEndian>()?;
let mut ret = String::new();
println!("read_string len = {:?}", len);
if len > 3000 {
let mut vec = vec![];
let result = buf.take(len as u64).read_to_end(&mut vec);
println!("vec = {:?}", vec);
println!("result = {:?}", result);
}
buf.take(len as u64).read_to_string(&mut ret)?;
Result::Ok(ret)
} bytes are [0, 0, 0, 255]. Bytes 0x0d0a for length are suspicious, CRLF? 0d 0a 00 00 00 ff, or a coincidence. 13, 10 (the last terminating sequence is 255 = 0xff): read Ok(69) = [0, 60, 188, 34, 0, parsing packet id 3c direction Clientbound in state Play |
"15, 13, 10, 0, 0, 0, 16, 13, 10, 0, 0, 0, 255" looks more like it should be maybe parsed as: 15, 13, 10, 0, 0, 0, (Note that metadata type 13 is NBT in 1.12.2, but changed in 1.13.2 to OptBlockID (VarInt) and NBT is 14.) https://wiki.vg/NBT says TAG_Compound is 10 and that every file will begin with this.
This is why it is trying to parse a String. What actually is this? |
It is technically possible to skip unparsed packets, since the length field is included, though not cleanest to do here, trying it for now to make progress. 0x3c EntityMetadata and 0x4d Advancements. Something about the entity metadata's NBT fields, and advancements structure is yet to be written. But now it fails on: thread 'main' panicked at 'Err: Err("Failed to read all of packet 0x1F, had 7 bytes left")', src/server/mod.rs:398:33 |
10, 0, 0, 0 is supposed to parse as an empty compound NBT tag. But src/nbt/mod.rs read_from calls Tag::read_type(10, buf), already passing the type byte (10). python3 nbtlib on Linux doesn't seem to parse correctly, or I am misusing it, but this library does: https://github.com/PrismarineJS/prismarine-nbt
and
so it is indeed two empty compound NBT tags (15, 13, 10, 0, 0, 0 and 16, 13, 10, 0, 0, 0). The parsing in Steven is somehow getting desynchronized. What is a similar packet using NBT which can be used as an example? Slot takes NBT, example packet: ClickWindow, but Steven represents Slot as impl Serializable for Option<nbt::NamedTag>{
fn read_from<R: io::Read>(buf: &mut R) -> Result<Option<nbt::NamedTag>, Error> {
let ty = buf.read_u8()?;
if ty == 0 {
Result::Ok(None)
} else {
let name = nbt::read_string(buf)?;
let tag = nbt::Tag::read_from(buf)?;
Result::Ok(Some(nbt::NamedTag(name, tag)))
}
}
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), Error> {
match *self {
Some(ref val) => {
buf.write_u8(10)?;
nbt::write_string(buf, &val.0)?;
val.1.write_to(buf)?;
}
None => buf.write_u8(0)?,
}
Result::Ok(())
}
} but TAG_STRING is "A length-prefixed UTF-8 string. The prefix is an unsigned short (thus 2 bytes) signifying the length of the string in bytes". Is this why there are three zeros, the first 00 00 immediately after 0a is the tag name, zero-length string? Then 00 is TAG_END? prismarine-js requires the full '\x0a\x00\x00\x00' buffer, it errors on parsing truncations '\x0a\x00\x00' (PartialReadError: Read error for value.compound : undefined), '\x0a\x00' (PartialReadError: Read error for name.$count : undefined), '\x0a' (same). But why does src/nbt/mod.rs read_type on compound tags bail early? 10 => {
let mut c = Tag::new_compound();
loop {
let ty = buf.read_u8()?;
if ty == 0 {
break;
}
let name: String = read_string(buf)?;
c.put(&name[..], Tag::read_type(ty, buf)?);
}
Ok(c)
} but if I change to break later, after reading the top-level string name: 10 => {
let mut c = Tag::new_compound();
loop {
let ty = buf.read_u8()?;
let name: String = read_string(buf)?;
if ty == 0 {
break;
}
c.put(&name[..], Tag::read_type(ty, buf)?);
}
Ok(c)
} then thread 'main' panicked at 'Err: IOError(Custom { kind: InvalidData, error: StringError("stream did not contain valid UTF-8") })', src/server/mod.rs:398:33. The last read string is:
|
0a 00 00 00 | | | \_ TAG_end | \__\ | TAG_string length? (2 bytes, '') | \ TAG_compound #40 (comment)
This reverts commit c8b07ae.
Parsing similarly to Optionnbt::NamedTag seems to work: metadata read_from index=15, ty=13 |
thread 'main' panicked at 'Err: Err("Failed to read all of packet 0x2B, had 1 bytes left")', src/server/mod.rs:398:33 |
read Ok(37) = [0, 26, 34, 123, 34, 116, 114, 97, 110, 115, 108, 97, 116, 101, 34, 58, 34, 100, 105, 115, 99, 111, 110, 110, 101, 99, 116, 46, 116, 105, 109, 101, 111, 117, 116, 34, 125] "UNHANDLED" is a translation problem in src/format.rs, this is actually: '\x00\x1a"{"translate":"disconnect.timeout"}' |
The first advancement: {
"data": {
"name": "advancements",
"params": {
"reset": true,
"advancementMapping": [
{
"key": "minecraft:adventure\/sleep_in_bed",
"value": {
"parentId": "minecraft:adventure\/root",
"displayData": {
"title": "{\"translate\":\"advancements.adventure.sleep_in_bed.title\"}",
"description": "{\"translate\":\"advancements.adventure.sleep_in_bed.description\"}",
"icon": {
"blockId": 355,
"itemCount": 1,
"itemDamage": 0
},
"frameType": 0,
"flags": { "_unused": 0, "hidden": 0, "show_toast": 1, "has_background_texture": 0 },
"xCord": 1,
"yCord": 4
},
"criteria": [ { "key": "slept_in_bed" } ],
} bytes from icon: 01 63 // 355 blockId something is seriously desynchronized, seems to be reading the blockId from the end of flags and beginning of xCord (02 3f = 575), then count from the middle of xCord (0x80 = 128), then damage from teh end of xCord (00 00 = 0), then the type of NBT from the beginning of yCord (0x40 = 64), reading too late in the stream, what gobbled it up earlier?
Advancement read_from earlier in Advancement, parent_id is read wrong: Advancement read_from "minecraft:adventure/sleep_in_bed" // id, parses ok |
Implemented the Option parsing (curiously, would have thought deserializing Option<> would do it for me, maybe only in packet definitions?), now it gets much further, but crashes at the end: Advancement read_from This means the Advancement mapping is now parsing entirely, but the next fields are not. Expect "identifiers": [] (array of strings, varint length), then progress mapping array of advancement progress. I have both of these defined inline: field identifiers: LenPrefixed<VarInt, String> =,
field progress: LenPrefixed<VarInt, LenPrefixed<VarInt, Option<i64>>> =, but progress is clearly wrong, missing two identifier strings: "The identifier of the advancement" and "The identifier of the criterion.", can't get away with simple definitions here (though maybe for criterion progress). |
This is about done, seems to work well. Going to use 1.12.2 as the mainline version for now, can backport to 1.11.2 later for https://github.com/iceiix/steven/issues/18 by undoing this merge. |
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format #40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format #40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
(except for src/nbt/mod.rs and src/types/metadata.rs) This reverts commit be6e1f7.
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format iceiix/steven#40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format iceiix/steven#40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format iceiix/steven#40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format iceiix/steven#40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
* Add new 1.12.2 packets and shift IDs CraftRecipeResponse AdvancementTab SelectAdvancementTab Advancements CraftingRecipeRequest UnlockRecipes CraftingBookData * Fix unlock recipes packet, add length-prefixed arrays https://wiki.vg/index.php?title=Protocol&oldid=14204#Unlock_Recipes * Update resources to 1.12.2 * Handle NBTTag metadata (value 13), parsed as nbt::NamedTag https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format iceiix/steven#40 (comment) * Fix entity packet IDs, 0x25 now is Entity https://wiki.vg/index.php?title=Protocol&oldid=14204#Entity * Add NBT long array (type 12) support https://wiki.vg/NBT#Specification * Entity metadata type is now a VarInt, not u8: https://wiki.vg/index.php?title=Entity_metadata&oldid=14048#Entity_Metadata_Format * Keep alives changed to longs, no longer VarInts https://wiki.vg/index.php?title=Protocol&oldid=14204#Keep_Alive_.28serverbound.29 * Parse CraftRecipeResponse (0x2b) * Add structs for advancements data * Implement Serializable trait for Advancement and AdvancementDisplay * Implement advancement progress parsing; advancement packet works * Particle packet adds fallingdust (46) with length 1 https://wiki.vg/index.php?title=Protocol&oldid=14204#Particle_2
https://github.com/iceiix/steven/issues/18
https://wiki.vg/Protocol_History#1.12.2
https://wiki.vg/index.php?title=Protocol&oldid=14204