aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/packets/status
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-15 23:10:55 -0600
committermat <github@matdoes.dev>2021-12-15 23:10:55 -0600
commit9642558f8f8d983a7087f15d68be8cf07a85f0c2 (patch)
tree5f0a967f005cd5db510a13ab290c8ad6669b25aa /azalea-protocol/src/packets/status
parent72aefe871ca4983431b1a0b707b472e73ffea836 (diff)
downloadazalea-drasl-9642558f8f8d983a7087f15d68be8cf07a85f0c2.tar.xz
azalea
Diffstat (limited to 'azalea-protocol/src/packets/status')
-rw-r--r--azalea-protocol/src/packets/status/clientbound_status_response_packet.rs58
-rw-r--r--azalea-protocol/src/packets/status/mod.rs66
-rw-r--r--azalea-protocol/src/packets/status/serverbound_status_request_packet.rs23
3 files changed, 147 insertions, 0 deletions
diff --git a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
new file mode 100644
index 00000000..1d8a3aa4
--- /dev/null
+++ b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
@@ -0,0 +1,58 @@
+use azalea_chat::component::Component;
+use serde::Deserialize;
+use serde_json::Value;
+use tokio::io::BufReader;
+
+use crate::mc_buf::Readable;
+
+use super::StatusPacket;
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct Version {
+ pub name: Component,
+ pub protocol: u32,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct SamplePlayer {
+ pub id: String,
+ pub name: String,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct Players {
+ pub max: u32,
+ pub online: u32,
+ pub sample: Vec<SamplePlayer>,
+}
+
+// the entire packet is just json, which is why it has deserialize
+#[derive(Clone, Debug, Deserialize)]
+pub struct ClientboundStatusResponsePacket {
+ pub description: Component,
+ pub favicon: Option<String>,
+ pub players: Players,
+ pub version: Version,
+}
+
+impl ClientboundStatusResponsePacket {
+ pub fn get(self) -> StatusPacket {
+ StatusPacket::ClientboundStatusResponsePacket(Box::new(self))
+ }
+
+ pub fn write(&self, _buf: &mut Vec<u8>) {}
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut BufReader<T>,
+ ) -> Result<StatusPacket, String> {
+ let status_string = buf.read_utf().await?;
+ let status_json: Value =
+ serde_json::from_str(status_string.as_str()).expect("Server status isn't valid JSON");
+
+ let packet = ClientboundStatusResponsePacket::deserialize(status_json)
+ .map_err(|e| e.to_string())?
+ .get();
+
+ Ok(packet)
+ }
+}
diff --git a/azalea-protocol/src/packets/status/mod.rs b/azalea-protocol/src/packets/status/mod.rs
new file mode 100644
index 00000000..ac6a34e1
--- /dev/null
+++ b/azalea-protocol/src/packets/status/mod.rs
@@ -0,0 +1,66 @@
+pub mod clientbound_status_response_packet;
+pub mod serverbound_status_request_packet;
+
+use async_trait::async_trait;
+use tokio::io::BufReader;
+
+use crate::connect::PacketFlow;
+
+use super::ProtocolPacket;
+
+#[derive(Clone, Debug)]
+pub enum StatusPacket
+where
+ Self: Sized,
+{
+ ServerboundStatusRequestPacket(
+ serverbound_status_request_packet::ServerboundStatusRequestPacket,
+ ),
+ ClientboundStatusResponsePacket(
+ Box<clientbound_status_response_packet::ClientboundStatusResponsePacket>,
+ ),
+}
+
+#[async_trait]
+impl ProtocolPacket for StatusPacket {
+ fn id(&self) -> u32 {
+ match self {
+ StatusPacket::ServerboundStatusRequestPacket(_packet) => 0x00,
+ StatusPacket::ClientboundStatusResponsePacket(_packet) => 0x00,
+ }
+ }
+
+ fn write(&self, buf: &mut Vec<u8>) {
+ match self {
+ StatusPacket::ServerboundStatusRequestPacket(packet) => packet.write(buf),
+ StatusPacket::ClientboundStatusResponsePacket(packet) => packet.write(buf),
+ }
+ }
+
+ /// Read a packet by its id, ConnectionProtocol, and flow
+ async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ id: u32,
+ flow: &PacketFlow,
+ buf: &mut BufReader<T>,
+ ) -> Result<StatusPacket, String>
+ where
+ Self: Sized,
+ {
+ match flow {
+ PacketFlow::ServerToClient => match id {
+ 0x00 => Ok(
+ clientbound_status_response_packet::ClientboundStatusResponsePacket::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown ServerToClient status packet id: {}", id)),
+ },
+ PacketFlow::ClientToServer => match id {
+ 0x00 => Ok(
+ serverbound_status_request_packet::ServerboundStatusRequestPacket::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown ClientToServer status packet id: {}", id)),
+ },
+ }
+ }
+}
diff --git a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
new file mode 100644
index 00000000..6a58da1f
--- /dev/null
+++ b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
@@ -0,0 +1,23 @@
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use super::StatusPacket;
+
+#[derive(Hash, Clone, Debug)]
+pub struct ServerboundStatusRequestPacket {}
+
+impl ServerboundStatusRequestPacket {
+ pub fn get(self) -> StatusPacket {
+ StatusPacket::ServerboundStatusRequestPacket(self)
+ }
+
+ pub fn write(&self, _buf: &mut Vec<u8>) {
+ panic!("ServerboundStatusRequestPacket::write not implemented")
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ _buf: &mut BufReader<T>,
+ ) -> Result<StatusPacket, String> {
+ Err("ServerboundStatusRequestPacket::read not implemented".to_string())
+ }
+}