diff options
author | Joey Sacchini <joey@sacchini.net> | 2020-10-09 18:42:32 -0400 |
---|---|---|
committer | Joey Sacchini <joey@sacchini.net> | 2020-10-09 18:42:32 -0400 |
commit | fafe72ac2d97bd5c94ad55bd55526c2dcba9b8ff (patch) | |
tree | de32700329d34bb811ca47170e4e41aeedeb68c0 /src/types.rs | |
parent | bda2a204d8a44d94a76ac94f4dd33682ac1b05d3 (diff) | |
download | mcproto-rs-fafe72ac2d97bd5c94ad55bd55526c2dcba9b8ff.tar.gz mcproto-rs-fafe72ac2d97bd5c94ad55bd55526c2dcba9b8ff.tar.bz2 mcproto-rs-fafe72ac2d97bd5c94ad55bd55526c2dcba9b8ff.zip |
fix broken lighting data and totally rewrite chat engine
Diffstat (limited to 'src/types.rs')
-rw-r--r-- | src/types.rs | 314 |
1 files changed, 2 insertions, 312 deletions
diff --git a/src/types.rs b/src/types.rs index 2082b56..cda622a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -4,6 +4,8 @@ use crate::utils::*; use crate::uuid::UUID4; use crate::*; +pub use super::chat::*; + #[cfg(test)] use crate::protocol::TestRandom; @@ -611,318 +613,6 @@ impl TestRandom for FixedInt { } } -// chat -#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] -pub struct Chat { - pub text: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub bold: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - pub italic: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - pub underlined: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - pub strikethrough: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - pub obfuscated: Option<bool>, - #[serde(skip_serializing_if = "Option::is_none")] - pub color: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - pub extra: Option<Vec<Chat>>, -} - -impl ToString for Chat { - fn to_string(&self) -> String { - self.extra - .as_ref() - .into_iter() - .flat_map(|v| v.into_iter()) - .map(|item| item.to_string()) - .fold(self.text.clone(), |acc, v| acc + v.as_str()) - } -} - -const SECTION_SYMBOL: char = 'ยง'; - -#[derive(PartialOrd, PartialEq, Debug, Copy, Clone)] -pub enum ColorCode { - Black, - DarkBlue, - DarkGreen, - DarkAqua, - DarkRed, - DarkPurple, - Gold, - Gray, - DarkGray, - Blue, - Green, - Aqua, - Red, - LightPurple, - Yellow, - White, -} - -impl ColorCode { - pub fn from_code(i: &char) -> Option<Self> { - match i { - '0' => Some(ColorCode::Black), - '1' => Some(ColorCode::DarkBlue), - '2' => Some(ColorCode::DarkGreen), - '3' => Some(ColorCode::DarkAqua), - '4' => Some(ColorCode::DarkRed), - '5' => Some(ColorCode::DarkPurple), - '6' => Some(ColorCode::Gold), - '7' => Some(ColorCode::Gray), - '8' => Some(ColorCode::DarkGray), - '9' => Some(ColorCode::Blue), - 'a' => Some(ColorCode::Green), - 'b' => Some(ColorCode::Aqua), - 'c' => Some(ColorCode::Red), - 'd' => Some(ColorCode::LightPurple), - 'e' => Some(ColorCode::Yellow), - 'f' => Some(ColorCode::White), - _ => None, - } - } - - pub fn to_code(&self) -> char { - match self { - ColorCode::Black => '0', - ColorCode::DarkBlue => '1', - ColorCode::DarkGreen => '2', - ColorCode::DarkAqua => '3', - ColorCode::DarkRed => '4', - ColorCode::DarkPurple => '5', - ColorCode::Gold => '6', - ColorCode::Gray => '7', - ColorCode::DarkGray => '8', - ColorCode::Blue => '9', - ColorCode::Green => 'a', - ColorCode::Aqua => 'b', - ColorCode::Red => 'c', - ColorCode::LightPurple => 'd', - ColorCode::Yellow => 'e', - ColorCode::White => 'f', - } - } - - pub fn from_name(name: &str) -> Option<Self> { - match name.to_ascii_lowercase().as_str() { - "black" => Some(ColorCode::Black), - "dark_blue" => Some(ColorCode::DarkBlue), - "dark_green" => Some(ColorCode::DarkGreen), - "dark_aqua" => Some(ColorCode::DarkAqua), - "dark_red" => Some(ColorCode::DarkRed), - "dark_purple" => Some(ColorCode::DarkPurple), - "gold" => Some(ColorCode::Gold), - "gray" => Some(ColorCode::Gray), - "dark_gray" => Some(ColorCode::DarkGray), - "blue" => Some(ColorCode::Blue), - "green" => Some(ColorCode::Green), - "aqua" => Some(ColorCode::Aqua), - "red" => Some(ColorCode::Red), - "light_purple" => Some(ColorCode::LightPurple), - "yellow" => Some(ColorCode::Yellow), - "white" => Some(ColorCode::White), - _ => None, - } - } - - pub fn name(&self) -> &str { - match self { - ColorCode::Black => "black", - ColorCode::DarkBlue => "dark_blue", - ColorCode::DarkGreen => "dark_green", - ColorCode::DarkAqua => "dark_aqua", - ColorCode::DarkRed => "dark_red", - ColorCode::DarkPurple => "dark_purple", - ColorCode::Gold => "gold", - ColorCode::Gray => "gray", - ColorCode::DarkGray => "dark_gray", - ColorCode::Blue => "blue", - ColorCode::Green => "green", - ColorCode::Aqua => "aqua", - ColorCode::Red => "red", - ColorCode::LightPurple => "light_purple", - ColorCode::Yellow => "yellow", - ColorCode::White => "white", - } - } -} - -#[derive(PartialOrd, PartialEq, Debug, Copy, Clone)] -pub enum Formatter { - Color(ColorCode), - Obfuscated, - Bold, - Strikethrough, - Underline, - Italic, - Reset, -} - -impl Formatter { - pub fn from_code(i: &char) -> Option<Self> { - match i.to_ascii_lowercase() { - 'k' => Some(Formatter::Obfuscated), - 'l' => Some(Formatter::Bold), - 'm' => Some(Formatter::Strikethrough), - 'n' => Some(Formatter::Underline), - 'o' => Some(Formatter::Italic), - 'r' => Some(Formatter::Reset), - _ => ColorCode::from_code(i).map(Formatter::Color), - } - } - - pub fn code(&self) -> char { - match self { - Formatter::Color(c) => c.to_code(), - Formatter::Obfuscated => 'k', - Formatter::Bold => 'l', - Formatter::Strikethrough => 'm', - Formatter::Underline => 'n', - Formatter::Italic => 'o', - Formatter::Reset => 'r', - } - } - - pub fn from_name(name: &str) -> Option<Self> { - match name.to_ascii_lowercase().as_str() { - "obfuscated" => Some(Formatter::Obfuscated), - "bold" => Some(Formatter::Bold), - "strikethrough" => Some(Formatter::Strikethrough), - "underline" => Some(Formatter::Underline), - "italic" => Some(Formatter::Italic), - "reset" => Some(Formatter::Reset), - _ => ColorCode::from_name(name).map(Formatter::Color), - } - } - - pub fn name(&self) -> &str { - match self { - Formatter::Obfuscated => "obfuscated", - Formatter::Bold => "bold", - Formatter::Strikethrough => "strikethrough", - Formatter::Underline => "underline", - Formatter::Italic => "italic", - Formatter::Reset => "reset", - Formatter::Color(c) => c.name(), - } - } -} - -impl ToString for Formatter { - fn to_string(&self) -> String { - vec![SECTION_SYMBOL, self.code()].into_iter().collect() - } -} - -impl Chat { - pub fn to_traditional(&self) -> String { - self.to_traditional_parts(Vec::<Formatter>::new().as_ref(), None) - } - - fn to_traditional_parts( - &self, - formatters: &Vec<Formatter>, - color: Option<ColorCode>, - ) -> String { - let mut own_formatters = formatters.clone(); - Self::update_formatter(&mut own_formatters, Formatter::Bold, &self.bold); - Self::update_formatter(&mut own_formatters, Formatter::Italic, &self.italic); - Self::update_formatter(&mut own_formatters, Formatter::Underline, &self.underlined); - Self::update_formatter( - &mut own_formatters, - Formatter::Strikethrough, - &self.strikethrough, - ); - Self::update_formatter(&mut own_formatters, Formatter::Obfuscated, &self.obfuscated); - - let own_color_option = self - .color - .as_ref() - .map(String::as_str) - .and_then(ColorCode::from_name) - .or(color); - - let own_color = own_color_option - .map(Formatter::Color) - .map(|f| f.to_string()); - - let own_formatter = own_formatters - .clone() - .into_iter() - .map(|f| f.to_string()) - .fold(String::new(), |acc, v| acc + v.as_str()); - - let own_color_str = match own_color { - Some(v) => v, - None => String::new(), - }; - - let own_out = own_formatter + own_color_str.as_str() + self.text.as_str(); - - self.extra - .as_ref() - .into_iter() - .flat_map(|v| v.into_iter()) - .map(|child| child.to_traditional_parts(&own_formatters, own_color_option)) - .fold(own_out, |acc, next| acc + next.as_str()) - } - - fn update_formatter(to: &mut Vec<Formatter>, formatter: Formatter, v: &Option<bool>) { - if !to.contains(&formatter) && v.unwrap_or(false) { - to.push(formatter) - } - } - - pub fn from_text(text: &str) -> Chat { - Chat { - text: text.to_owned(), - bold: None, - italic: None, - underlined: None, - strikethrough: None, - obfuscated: None, - color: None, - extra: None, - } - } -} - -impl Serialize for Chat { - fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult { - serde_json::to_string(self) - .map_err(move |err| { - SerializeErr::FailedJsonEncode(format!("failed to serialize chat {:?}", err)) - })? - .mc_serialize(to) - } -} - -impl Deserialize for Chat { - fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> { - String::mc_deserialize(data)?.try_map(move |str| { - serde_json::from_str(str.as_str()).map_err(move |err| { - DeserializeErr::FailedJsonDeserialize(format!( - "failed to deserialize chat {:?}", - err - )) - }) - }) - } -} - -#[cfg(test)] -impl TestRandom for Chat { - fn test_gen_random() -> Self { - let str = String::test_gen_random(); - Chat::from_text(str.as_str()) - } -} - #[derive(Default)] pub struct BytesSerializer { data: Vec<u8>, |