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>),
Compound(HashMap<String, Tag>),
IntArray(Vec<i32>),
LongArray(Vec<i64>),
}
#[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 {
match *self {
Tag::End => 0,
@ -169,6 +178,7 @@ impl Tag {
Tag::List(_) => 9,
Tag::Compound(_) => 10,
Tag::IntArray(_) => 11,
Tag::LongArray(_) => 12,
}
}
@ -217,6 +227,14 @@ impl Tag {
}
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())),
}
}
@ -267,6 +285,12 @@ impl Serializable for Tag {
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(())
}

View File

@ -21,6 +21,7 @@ use crate::protocol::Serializable;
use crate::format;
use crate::item;
use crate::shared::Position;
use crate::nbt;
pub struct MetadataKey<T: MetaValue> {
index: i32,
@ -68,7 +69,7 @@ impl Serializable for Metadata {
if index == 0xFF {
break;
}
let ty = u8::read_from(buf)?;
let ty = protocol::VarInt::read_from(buf)?.0;
match ty {
0 => m.put_raw(index, i8::read_from(buf)?),
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),
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())),
}
}
@ -164,6 +174,11 @@ impl Serializable for Metadata {
u8::write_to(&11, 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)?;
@ -202,6 +217,7 @@ pub enum Value {
Direction(protocol::VarInt), // TODO: Proper type
OptionalUUID(Option<protocol::UUID>),
Block(u16), // TODO: Proper type
NBTTag(nbt::NamedTag),
}
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)]
mod test {
use super::*;