1.12.2 protocol support (340) (#40)

* 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
https://github.com/iceiix/steven/pull/40#issuecomment-443454757

* 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
This commit is contained in:
iceiix 2018-12-02 19:32:52 -08:00 committed by ice_iix
parent 9504be550f
commit ad8bcf6aba
2 changed files with 53 additions and 1 deletions

View File

@ -34,6 +34,7 @@ pub enum Tag {
List(Vec<Tag>), List(Vec<Tag>),
Compound(HashMap<String, Tag>), Compound(HashMap<String, Tag>),
IntArray(Vec<i32>), IntArray(Vec<i32>),
LongArray(Vec<i64>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -155,6 +156,14 @@ impl Tag {
} }
} }
pub fn as_long_array(&self) -> Option<&[i64]> {
match *self {
Tag::LongArray(ref val) => Some(&val[..]),
_ => None,
}
}
fn internal_id(&self) -> u8 { fn internal_id(&self) -> u8 {
match *self { match *self {
Tag::End => 0, Tag::End => 0,
@ -169,6 +178,7 @@ impl Tag {
Tag::List(_) => 9, Tag::List(_) => 9,
Tag::Compound(_) => 10, Tag::Compound(_) => 10,
Tag::IntArray(_) => 11, Tag::IntArray(_) => 11,
Tag::LongArray(_) => 12,
} }
} }
@ -217,6 +227,14 @@ impl Tag {
} }
data data
})), })),
12 => Ok(Tag::LongArray({
let len: i32 = Serializable::read_from(buf)?;
let mut data = Vec::with_capacity(len as usize);
for _ in 0..len {
data.push(buf.read_i64::<BigEndian>()?);
}
data
})),
_ => Err(protocol::Error::Err("invalid tag".to_owned())), _ => Err(protocol::Error::Err("invalid tag".to_owned())),
} }
} }
@ -267,6 +285,12 @@ impl Serializable for Tag {
v.write_to(buf)?; v.write_to(buf)?;
} }
} }
Tag::LongArray(ref val) => {
(val.len() as i32).write_to(buf)?;
for v in val {
v.write_to(buf)?;
}
}
} }
Result::Ok(()) Result::Ok(())
} }

View File

@ -21,6 +21,7 @@ use crate::protocol::Serializable;
use crate::format; use crate::format;
use crate::item; use crate::item;
use crate::shared::Position; use crate::shared::Position;
use crate::nbt;
pub struct MetadataKey<T: MetaValue> { pub struct MetadataKey<T: MetaValue> {
index: i32, index: i32,
@ -68,7 +69,7 @@ impl Serializable for Metadata {
if index == 0xFF { if index == 0xFF {
break; break;
} }
let ty = u8::read_from(buf)?; let ty = protocol::VarInt::read_from(buf)?.0;
match ty { match ty {
0 => m.put_raw(index, i8::read_from(buf)?), 0 => m.put_raw(index, i8::read_from(buf)?),
1 => m.put_raw(index, protocol::VarInt::read_from(buf)?.0), 1 => m.put_raw(index, protocol::VarInt::read_from(buf)?.0),
@ -98,6 +99,15 @@ impl Serializable for Metadata {
} }
} }
12 => m.put_raw(index, protocol::VarInt::read_from(buf)?.0 as u16), 12 => m.put_raw(index, protocol::VarInt::read_from(buf)?.0 as u16),
13 => {
let ty = u8::read_from(buf)?;
if ty != 0 {
let name = nbt::read_string(buf)?;
let tag = nbt::Tag::read_from(buf)?;
m.put_raw(index, nbt::NamedTag(name, tag));
}
}
_ => return Err(protocol::Error::Err("unknown metadata type".to_owned())), _ => return Err(protocol::Error::Err("unknown metadata type".to_owned())),
} }
} }
@ -164,6 +174,11 @@ impl Serializable for Metadata {
u8::write_to(&11, buf)?; u8::write_to(&11, buf)?;
protocol::VarInt(*val as i32).write_to(buf)?; protocol::VarInt(*val as i32).write_to(buf)?;
} }
Value::NBTTag(ref _val) => {
u8::write_to(&13, buf)?;
// TODO: write NBT tags metadata
//nbt::Tag(*val).write_to(buf)?;
}
} }
} }
u8::write_to(&0xFF, buf)?; u8::write_to(&0xFF, buf)?;
@ -202,6 +217,7 @@ pub enum Value {
Direction(protocol::VarInt), // TODO: Proper type Direction(protocol::VarInt), // TODO: Proper type
OptionalUUID(Option<protocol::UUID>), OptionalUUID(Option<protocol::UUID>),
Block(u16), // TODO: Proper type Block(u16), // TODO: Proper type
NBTTag(nbt::NamedTag),
} }
pub trait MetaValue { pub trait MetaValue {
@ -365,6 +381,18 @@ impl MetaValue for u16 {
} }
} }
impl MetaValue for nbt::NamedTag {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::NBTTag(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::NBTTag(self)
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;