diff --git a/Cargo.lock b/Cargo.lock index 08d718a1..f82d7659 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -307,6 +307,8 @@ dependencies = [ "async-trait", "byteorder", "bytes", + "minecraft-chat", + "serde_json", "thiserror", "tokio", "tokio-util", diff --git a/minecraft-chat/src/base_component.rs b/minecraft-chat/src/base_component.rs index 30e66173..40fb3909 100644 --- a/minecraft-chat/src/base_component.rs +++ b/minecraft-chat/src/base_component.rs @@ -1,6 +1,6 @@ use crate::{component::Component, style::Style}; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct BaseComponent { // implements mutablecomponent pub siblings: Vec, diff --git a/minecraft-chat/src/component.rs b/minecraft-chat/src/component.rs index 3135c3ba..958440ba 100644 --- a/minecraft-chat/src/component.rs +++ b/minecraft-chat/src/component.rs @@ -9,7 +9,7 @@ use crate::{ translatable_component::{StringOrComponent, TranslatableComponent}, }; -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Component { TextComponent(TextComponent), TranslatableComponent(TranslatableComponent), @@ -23,9 +23,9 @@ impl Component { // if it's primitive, make it a text component if !json.is_array() && !json.is_object() { - component = Component::TextComponent(TextComponent::new( + return Ok(Component::TextComponent(TextComponent::new( json.as_str().unwrap_or("").to_string(), - )); + ))); } // if it's an object, do things with { text } and stuff else if json.is_object() { @@ -41,11 +41,11 @@ impl Component { // if it's a string component with no styling and no siblings, just add a string to with_array // otherwise add the component to the array let c = Component::new(&with[i])?; - if let Component::TextComponent(textComponent) = c { - if textComponent.base.siblings.len() == 0 - && textComponent.base.style.is_empty() + if let Component::TextComponent(text_component) = c { + if text_component.base.siblings.len() == 0 + && text_component.base.style.is_empty() { - with_array.push(StringOrComponent::String(textComponent.text)); + with_array.push(StringOrComponent::String(text_component.text)); break; } } @@ -141,7 +141,7 @@ impl Component { return Ok(component); } // ok so it's not an object, if it's an array deserialize every item - if !json.is_array() { + else if !json.is_array() { return Err(format!("Don't know how to turn {} into a Component", json)); } let json_array = json.as_array().unwrap(); @@ -211,7 +211,7 @@ impl Component { styled_component.push_str(&sibling.to_ansi(Some(current_style))); } - if is_base_style { + if is_base_style && ansi_text.len() > 0 { styled_component.push_str("\x1b[m"); } diff --git a/minecraft-chat/src/lib.rs b/minecraft-chat/src/lib.rs index b7035e13..5e9f1e3a 100644 --- a/minecraft-chat/src/lib.rs +++ b/minecraft-chat/src/lib.rs @@ -6,6 +6,7 @@ extern crate lazy_static; pub mod base_component; pub mod component; +pub mod splitter; pub mod style; pub mod text_component; pub mod translatable_component; diff --git a/minecraft-chat/src/splitter.rs b/minecraft-chat/src/splitter.rs new file mode 100644 index 00000000..812c3365 --- /dev/null +++ b/minecraft-chat/src/splitter.rs @@ -0,0 +1,7 @@ +//! Used for splitting text +//! This includes wrapping long lines and applying legacy color formats. +//! I'm not sure why applying legacy color formats is done here but that's the way Minecraft does it. + +use crate::component::Component; + +fn split_lines(component: Component) {} diff --git a/minecraft-chat/src/text_component.rs b/minecraft-chat/src/text_component.rs index e950ee00..bd47d671 100644 --- a/minecraft-chat/src/text_component.rs +++ b/minecraft-chat/src/text_component.rs @@ -1,6 +1,6 @@ use crate::{base_component::BaseComponent, component::Component}; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct TextComponent { pub base: BaseComponent, pub text: String, diff --git a/minecraft-chat/src/translatable_component.rs b/minecraft-chat/src/translatable_component.rs index 327c5e07..0709f7bf 100644 --- a/minecraft-chat/src/translatable_component.rs +++ b/minecraft-chat/src/translatable_component.rs @@ -1,12 +1,12 @@ use crate::{base_component::BaseComponent, component::Component}; -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum StringOrComponent { String(String), Component(Component), } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct TranslatableComponent { pub base: BaseComponent, pub key: String, diff --git a/minecraft-chat/tests/integration_test.rs b/minecraft-chat/tests/integration_test.rs index 4c8a39aa..a454ad3b 100644 --- a/minecraft-chat/tests/integration_test.rs +++ b/minecraft-chat/tests/integration_test.rs @@ -65,3 +65,10 @@ fn complex_ansi_test() { ) ); } + +#[test] +fn component_from_string() { + let j: Value = serde_json::from_str("\"foo\"").unwrap(); + let component = Component::new(&j).unwrap(); + assert_eq!(component.to_ansi(None), "foo"); +} diff --git a/minecraft-protocol/Cargo.toml b/minecraft-protocol/Cargo.toml index 80e2b625..7894ecfd 100644 --- a/minecraft-protocol/Cargo.toml +++ b/minecraft-protocol/Cargo.toml @@ -14,3 +14,5 @@ tokio = {version = "^1.14.0", features = ["io-util", "net", "macros"]} tokio-util = "^0.6.9" trust-dns-resolver = "^0.20.3" async-trait = "0.1.51" +minecraft-chat = { path = "../minecraft-chat" } +serde_json = "^1.0.72" diff --git a/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs b/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs index b61562cf..5099952c 100644 --- a/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs +++ b/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; -use std::hash::Hash; +use minecraft_chat::component::Component; +use serde_json::Value; use tokio::io::BufReader; use crate::{ @@ -7,9 +8,29 @@ use crate::{ packets::{Packet, PacketTrait}, }; -#[derive(Hash, Clone, Debug)] +#[derive(Clone, Debug)] +struct Version { + name: String, + protocol: u32, +} + +#[derive(Clone, Debug)] +struct SamplePlayer { + id: String, + name: String, +} + +#[derive(Clone, Debug)] +struct Players { + max: u32, + online: u32, + sample: Vec, +} + +#[derive(Clone, Debug)] pub struct ClientboundStatusResponsePacket { - status: String, + // version: Version, + description: Component, } #[async_trait] @@ -23,8 +44,16 @@ impl PacketTrait for ClientboundStatusResponsePacket { async fn read( buf: &mut BufReader, ) -> Result { - let status = mc_buf::read_utf(buf).await?; + let status_string = mc_buf::read_utf(buf).await?; + let status_json: Value = + serde_json::from_str(status_string.as_str()).expect("Server status isn't valid JSON"); + let description_string: &Value = status_json.get("description").unwrap(); + // this.status = GsonHelper.fromJson(GSON, friendlyByteBuf.readUtf(32767), ServerStatus.class); - Ok(ClientboundStatusResponsePacket { status }.get()) + Ok(ClientboundStatusResponsePacket { + // version: status_json.get("version"), + description: Component::new(&description_string)?, + } + .get()) } }