diff --git a/src/status.rs b/src/status.rs index c1ac512..89e04de 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,256 +1,4 @@ -// Yeahbut December 2023 +// Yeahbut September 2025 -pub mod clientbound { - - use serde::{Serialize, Deserialize, Serializer, Deserializer}; - use serde::de::{self, Visitor, MapAccess}; - use std::fmt; - - use crate::mc_types::{self, Result, Packet, PacketError}; - - #[derive(Serialize, Deserialize)] - pub struct StatusVersion { - pub name: String, - pub protocol: i32, - } - - pub enum StatusDescription { - String(String), - Chat(mc_types::Chat), - } - - impl Serialize for StatusDescription { - fn serialize(&self, serializer: S) - -> std::result::Result - where - S: Serializer, - { - match *self { - StatusDescription::String(ref s) => serializer.serialize_str(s), - StatusDescription::Chat(ref c) => c.serialize(serializer), - } - } - } - - impl<'de> Deserialize<'de> for StatusDescription { - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - struct StatusDescriptionVisitor; - - impl<'de> Visitor<'de> for StatusDescriptionVisitor { - type Value = StatusDescription; - - fn expecting(&self, formatter: &mut fmt::Formatter) - -> fmt::Result - { - formatter.write_str( - "a string or a map representing a Chat object") - } - - fn visit_str(self, value: &str) - -> std::result::Result - where - E: de::Error, - { - Ok(StatusDescription::String(value.to_string())) - } - - fn visit_map(self, map: M) - -> std::result::Result - where - M: MapAccess<'de>, - { - let chat = mc_types::Chat::deserialize( - de::value::MapAccessDeserializer::new(map))?; - Ok(StatusDescription::Chat(chat)) - } - } - - deserializer.deserialize_any(StatusDescriptionVisitor) - } - } - - #[derive(Serialize, Deserialize)] - pub struct StatusPlayerInfo { - pub name: String, - pub id: String, - } - - #[derive(Serialize, Deserialize)] - pub struct StatusPlayers { - pub max: i32, - pub online: i32, - #[serde(skip_serializing_if = "Option::is_none")] - pub sample: Option> - } - - #[allow(non_snake_case)] - #[derive(Serialize, Deserialize)] - pub struct StatusResponseData { - pub version: StatusVersion, - pub description: StatusDescription, - pub players: StatusPlayers, - #[serde(skip_serializing_if = "Option::is_none")] - pub favicon: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub enforcesSecureChat: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub previewsChat: Option, - } - - pub enum StatusPackets { - Status(Status), - Ping(Ping), - } - - impl StatusPackets { - pub async fn read( - conn: &mut T, - ) -> Result { - let mut data = conn.read_data().await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Status::packet_id() { - return Ok(Self::Status(Status::get(&mut data)?)) - } else if packet_id == Ping::packet_id() { - return Ok(Self::Ping(Ping::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId(packet_id))) - } - } - } - - pub struct Status { - pub response: String - } - - impl Status { - - pub fn from_json(data: StatusResponseData) -> Result { - Ok(Self { - response: serde_json::to_string(&data)? - }) - } - - pub fn get_json(&self) -> Result { - Ok(serde_json::from_str(&self.response)?) - } - - } - - impl Packet for Status { - - fn packet_id() -> i32 {0} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - response: mc_types::get_string(&mut data)? - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_string(&self.response)); - - data - } - - } - - pub struct Ping { - pub payload: i64 - } - - impl Packet for Ping { - - fn packet_id() -> i32 {1} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - payload: mc_types::get_i64(&mut data) - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_i64(self.payload)); - - data - } - - } - -} - -pub mod serverbound { - - use crate::mc_types::{self, Result, Packet, PacketError}; - - pub enum StatusPackets { - Status(Status), - Ping(Ping), - } - - impl StatusPackets { - pub async fn read( - conn: &mut T, - ) -> Result { - let mut data = conn.read_data().await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Status::packet_id() { - return Ok(Self::Status(Status::get(&mut data)?)) - } else if packet_id == Ping::packet_id() { - return Ok(Self::Ping(Ping::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId(packet_id))) - } - } - } - - pub struct Status {} - - impl Packet for Status { - - fn packet_id() -> i32 {0} - - fn get(_data: &mut Vec) -> Result { - Ok(Self {}) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - - data - } - - } - - pub struct Ping { - pub payload: i64 - } - - impl Packet for Ping { - - fn packet_id() -> i32 {1} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - payload: mc_types::get_i64(&mut data) - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_i64(self.payload)); - - data - } - - } - -} +pub mod clientbound; +pub mod serverbound; diff --git a/src/status/clientbound.rs b/src/status/clientbound.rs new file mode 100644 index 0000000..bff3c94 --- /dev/null +++ b/src/status/clientbound.rs @@ -0,0 +1,125 @@ +// Yeahbut September 2025 + +use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::de::{self, Visitor, MapAccess}; +use std::fmt; + +use crate::mc_types::{self, Result, Packet, PacketError}; + +#[derive(Serialize, Deserialize)] +pub struct StatusVersion { + pub name: String, + pub protocol: i32, +} + +pub enum StatusDescription { + String(String), + Chat(mc_types::Chat), +} + +impl Serialize for StatusDescription { + fn serialize(&self, serializer: S) + -> std::result::Result + where + S: Serializer, + { + match *self { + StatusDescription::String(ref s) => serializer.serialize_str(s), + StatusDescription::Chat(ref c) => c.serialize(serializer), + } + } +} + +impl<'de> Deserialize<'de> for StatusDescription { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + struct StatusDescriptionVisitor; + + impl<'de> Visitor<'de> for StatusDescriptionVisitor { + type Value = StatusDescription; + + fn expecting(&self, formatter: &mut fmt::Formatter) + -> fmt::Result + { + formatter.write_str( + "a string or a map representing a Chat object") + } + + fn visit_str(self, value: &str) + -> std::result::Result + where + E: de::Error, + { + Ok(StatusDescription::String(value.to_string())) + } + + fn visit_map(self, map: M) + -> std::result::Result + where + M: MapAccess<'de>, + { + let chat = mc_types::Chat::deserialize( + de::value::MapAccessDeserializer::new(map))?; + Ok(StatusDescription::Chat(chat)) + } + } + + deserializer.deserialize_any(StatusDescriptionVisitor) + } +} + +#[derive(Serialize, Deserialize)] +pub struct StatusPlayerInfo { + pub name: String, + pub id: String, +} + +#[derive(Serialize, Deserialize)] +pub struct StatusPlayers { + pub max: i32, + pub online: i32, + #[serde(skip_serializing_if = "Option::is_none")] + pub sample: Option> +} + +#[allow(non_snake_case)] +#[derive(Serialize, Deserialize)] +pub struct StatusResponseData { + pub version: StatusVersion, + pub description: StatusDescription, + pub players: StatusPlayers, + #[serde(skip_serializing_if = "Option::is_none")] + pub favicon: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub enforcesSecureChat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub previewsChat: Option, +} + +#[derive(Packet)] +#[packet(id = 0, name = "Status")] +pub struct Status { + pub response: String +} + +impl Status { + + pub fn from_json(data: StatusResponseData) -> Result { + Ok(Self { + response: serde_json::to_string(&data)? + }) + } + + pub fn get_json(&self) -> Result { + Ok(serde_json::from_str(&self.response)?) + } + +} + +#[derive(Packet)] +#[packet(id = 1, name = "Ping")] +pub struct Ping { + pub payload: i64 +} diff --git a/src/status/serverbound.rs b/src/status/serverbound.rs new file mode 100644 index 0000000..ae3ce94 --- /dev/null +++ b/src/status/serverbound.rs @@ -0,0 +1,13 @@ +// Yeahbut September 2025 + +use crate::mc_types::{self, Result, Packet}; + +#[derive(Packet)] +#[packet(id = 0, name = "Status")] +pub struct Status {} + +#[derive(Packet)] +#[packet(id = 1, name = "Ping")] +pub struct Ping { + pub payload: i64 +}