aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/packets/login
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/login
parent72aefe871ca4983431b1a0b707b472e73ffea836 (diff)
downloadazalea-drasl-9642558f8f8d983a7087f15d68be8cf07a85f0c2.tar.xz
azalea
Diffstat (limited to 'azalea-protocol/src/packets/login')
-rw-r--r--azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs41
-rw-r--r--azalea-protocol/src/packets/login/clientbound_hello_packet.rs38
-rw-r--r--azalea-protocol/src/packets/login/mod.rs63
-rw-r--r--azalea-protocol/src/packets/login/serverbound_hello_packet.rs27
4 files changed, 169 insertions, 0 deletions
diff --git a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
new file mode 100644
index 00000000..093176eb
--- /dev/null
+++ b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
@@ -0,0 +1,41 @@
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use crate::mc_buf::{self, Readable, Writable};
+
+use super::LoginPacket;
+
+#[derive(Hash, Clone, Debug)]
+pub struct ClientboundCustomQueryPacket {
+ pub transaction_id: u32,
+ // TODO: this should be a resource location
+ pub identifier: String,
+ pub data: Vec<u8>,
+}
+
+impl ClientboundCustomQueryPacket {
+ pub fn get(self) -> LoginPacket {
+ LoginPacket::ClientboundCustomQueryPacket(self)
+ }
+
+ pub fn write(&self, buf: &mut Vec<u8>) {
+ buf.write_varint(self.transaction_id as i32).unwrap();
+ buf.write_utf(&self.identifier).unwrap();
+ buf.write_bytes(&self.data).unwrap();
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut BufReader<T>,
+ ) -> Result<LoginPacket, String> {
+ let transaction_id = buf.read_varint().await?.0 as u32;
+ // TODO: this should be a resource location
+ let identifier = buf.read_utf().await?;
+ let data = buf.read_bytes(1048576).await?;
+ Ok(ClientboundCustomQueryPacket {
+ transaction_id,
+ identifier,
+ data,
+ }
+ .get())
+ }
+}
diff --git a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
new file mode 100644
index 00000000..36a48706
--- /dev/null
+++ b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
@@ -0,0 +1,38 @@
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use crate::mc_buf::Readable;
+
+use super::LoginPacket;
+
+#[derive(Hash, Clone, Debug)]
+pub struct ClientboundHelloPacket {
+ pub server_id: String,
+ pub public_key: Vec<u8>,
+ pub nonce: Vec<u8>,
+}
+
+impl ClientboundHelloPacket {
+ pub fn get(self) -> LoginPacket {
+ LoginPacket::ClientboundHelloPacket(self)
+ }
+
+ pub fn write(&self, _buf: &mut Vec<u8>) {
+ panic!("ClientboundHelloPacket::write not implemented")
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut BufReader<T>,
+ ) -> Result<LoginPacket, String> {
+ let server_id = buf.read_utf_with_len(20).await?;
+ let public_key = buf.read_byte_array().await?;
+ let nonce = buf.read_byte_array().await?;
+
+ Ok(ClientboundHelloPacket {
+ server_id,
+ public_key,
+ nonce,
+ }
+ .get())
+ }
+}
diff --git a/azalea-protocol/src/packets/login/mod.rs b/azalea-protocol/src/packets/login/mod.rs
new file mode 100644
index 00000000..f0ed6717
--- /dev/null
+++ b/azalea-protocol/src/packets/login/mod.rs
@@ -0,0 +1,63 @@
+pub mod clientbound_custom_query_packet;
+pub mod clientbound_hello_packet;
+pub mod serverbound_hello_packet;
+
+use async_trait::async_trait;
+use tokio::io::BufReader;
+
+use crate::connect::PacketFlow;
+
+use super::ProtocolPacket;
+
+#[derive(Clone, Debug)]
+pub enum LoginPacket
+where
+ Self: Sized,
+{
+ ClientboundCustomQueryPacket(clientbound_custom_query_packet::ClientboundCustomQueryPacket),
+ ServerboundHelloPacket(serverbound_hello_packet::ServerboundHelloPacket),
+ ClientboundHelloPacket(clientbound_hello_packet::ClientboundHelloPacket),
+}
+
+#[async_trait]
+impl ProtocolPacket for LoginPacket {
+ fn id(&self) -> u32 {
+ match self {
+ LoginPacket::ClientboundCustomQueryPacket(_packet) => 0x04,
+ LoginPacket::ServerboundHelloPacket(_packet) => 0x00,
+ LoginPacket::ClientboundHelloPacket(_packet) => 0x01,
+ }
+ }
+
+ fn write(&self, buf: &mut Vec<u8>) {
+ match self {
+ LoginPacket::ClientboundCustomQueryPacket(packet) => packet.write(buf),
+ LoginPacket::ServerboundHelloPacket(packet) => packet.write(buf),
+ LoginPacket::ClientboundHelloPacket(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<LoginPacket, String>
+ where
+ Self: Sized,
+ {
+ Ok(match flow {
+ PacketFlow::ServerToClient => match id {
+ 0x01 => clientbound_hello_packet::ClientboundHelloPacket::read(buf).await?,
+ 0x04 => {
+ clientbound_custom_query_packet::ClientboundCustomQueryPacket::read(buf).await?
+ }
+ _ => return Err(format!("Unknown ServerToClient status packet id: {}", id)),
+ },
+ PacketFlow::ClientToServer => match id {
+ 0x00 => serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
+ _ => return Err(format!("Unknown ClientToServer status packet id: {}", id)),
+ },
+ })
+ }
+}
diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
new file mode 100644
index 00000000..32a6dadc
--- /dev/null
+++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
@@ -0,0 +1,27 @@
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use crate::mc_buf::Writable;
+
+use super::LoginPacket;
+
+#[derive(Hash, Clone, Debug)]
+pub struct ServerboundHelloPacket {
+ pub username: String,
+}
+
+impl ServerboundHelloPacket {
+ pub fn get(self) -> LoginPacket {
+ LoginPacket::ServerboundHelloPacket(self)
+ }
+
+ pub fn write(&self, buf: &mut Vec<u8>) {
+ buf.write_utf(&self.username).unwrap();
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ _buf: &mut BufReader<T>,
+ ) -> Result<LoginPacket, String> {
+ Err("ServerboundHelloPacket::read not implemented".to_string())
+ }
+}