From df9471c74b0a1e156efafb31d41065925937ed24 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sat, 5 Aug 2023 12:11:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E7=90=86=EF=BC=8C=E5=A4=AA=E5=90=88?= =?UTF-8?q?=E7=90=86=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/read.rs | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 4 deletions(-) diff --git a/src/read.rs b/src/read.rs index 4115def..0cf2574 100644 --- a/src/read.rs +++ b/src/read.rs @@ -61,7 +61,7 @@ pub mod read { /// 直接读取长度和值 不带名称 /// 主要是为了可以直接递归 ( - pub fn read_nbt_list(value: &mut Reader) -> Vec { + pub fn from_nbt_list(value: &mut Reader) -> Vec { // 读取长度 let mut buff = [0_u8; 4]; _ = value.read(&mut buff).unwrap(); @@ -122,7 +122,7 @@ pub mod read { // 要命 (虽说没 Compound 那么麻烦) // 直接递归就行 for _ in 0..len { - vec.push(NbtItem::from(read_nbt_list(value))); + vec.push(NbtItem::from(from_nbt_list(value))); } } [0x0A] => { @@ -157,13 +157,121 @@ pub mod read { } vec } + + /// 直接读取长度和值 不带名称 + /// 只不过 Compound 不带长度,得自己试 + pub fn from_compound(value: &mut Reader) -> NbtList { + // 进来直接是 values + // loop 读取长度 name len name value value + // 直到一个 NbtEnd + let mut map: HashMap, NbtItem> = HashMap::new(); + loop { + let mut type_tag = [0_u8; 1]; + _ = value.read(&mut type_tag).unwrap(); + if type_tag == [0x00] { + // NbtEnd + break; + } + // 读取 name + // 直接调之前的方法读 + let name = NbtValue::from_string(value).as_string().unwrap(); + // 读取 value + let nbt_value: NbtItem = match type_tag { + [0x01] => NbtItem::Value(NbtValue::from_bool(value)), + [0x02] => NbtItem::Value(NbtValue::from_i16(value)), + [0x03] => NbtItem::Value(NbtValue::from_i32(value)), + [0x04] => NbtItem::Value(NbtValue::from_i64(value)), + [0x05] => NbtItem::Value(NbtValue::from_f32(value)), + [0x06] => NbtItem::Value(NbtValue::from_f64(value)), + [0x07] => NbtItem::from(from_bool_array(value)), + [0x08] => NbtItem::Value(NbtValue::from_string(value)), + [0x09] => NbtItem::from(from_nbt_list(value)), + [0x0A] => NbtItem::from(from_compound(value)), + [0x0B] => NbtItem::from(from_i32_array(value)), + [0x0C] => NbtItem::from(from_i64_array(value)), + _ => { + panic!( + "{}", + format!( + "WTF while reading Nbt Compound \ntype: {:?}\nreader pos: {:?}\nname: {:?}", + type_tag, + value.position(), + name + ) + ) + } + }; + // 读取完了,放进去 + map.insert(name, nbt_value); + } + NbtList::from(map) + } +} + +pub enum NbtStatus { + /// 读取到了 NbtEnd + End, + /// 继续中 + Going(NbtItem), + /// 读取错误 + Error(std::io::Error), } /// NbtItem /// 完整的读取逻辑就在这里了 /// 来力 #[allow(unused)] -impl From> for NbtItem { +impl TryFrom> for NbtItem { + type Error = std::io::Error; + /// 完整逻辑~ - fn from(value: Reader) -> NbtItem { todo!() } + fn try_from(in_value: Reader) -> Result { + let mut value: Reader = in_value.clone(); + let mut items: Vec = Vec::new(); + loop { + // 读取类型 + let mut buff = [0_u8; 1]; + _ = value.read(&mut buff).unwrap(); + let type_code: NbtStatus = match buff { + [0x00] => NbtStatus::End, + [0x01] => NbtStatus::Going(NbtItem::Value(NbtValue::from_bool(&mut value))), + [0x02] => NbtStatus::Going(NbtItem::Value(NbtValue::from_i16(&mut value))), + [0x03] => NbtStatus::Going(NbtItem::Value(NbtValue::from_i32(&mut value))), + [0x04] => NbtStatus::Going(NbtItem::Value(NbtValue::from_i64(&mut value))), + [0x05] => NbtStatus::Going(NbtItem::Value(NbtValue::from_f32(&mut value))), + [0x06] => NbtStatus::Going(NbtItem::Value(NbtValue::from_f64(&mut value))), + [0x07] => NbtStatus::Going(NbtItem::from(read::from_bool_array(&mut value))), + [0x08] => NbtStatus::Going(NbtItem::Value(NbtValue::from_string(&mut value))), + [0x09] => NbtStatus::Going(NbtItem::from(read::from_nbt_list(&mut value))), + [0x0A] => NbtStatus::Going(NbtItem::from(read::from_compound(&mut value))), + [0x0B] => NbtStatus::Going(NbtItem::from(read::from_i32_array(&mut value))), + [0x0C] => NbtStatus::Going(NbtItem::from(read::from_i64_array(&mut value))), + _ => NbtStatus::Error(std::io::Error::new( + std::io::ErrorKind::InvalidData, + format!( + "WTF while reading Nbt Item \ntype: {:?}\nreader pos: {:?}", + buff, + value.position() + ), + )), + }; + match type_code { + NbtStatus::End => { + break; + } + NbtStatus::Going(item) => { + items.push(item); + } + NbtStatus::Error(e) => { + return Err(e); + } + } + } + // 理论上 长度应该为 2 + return if items.len() >= 3 { + Ok(NbtItem::Array(NbtList::from(items))) + } else { + Ok(items[0].clone()) + }; + } }