diff options
| author | mat <github@matdoes.dev> | 2021-12-10 00:54:58 -0600 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2021-12-10 00:54:58 -0600 |
| commit | be762fc5d37ba48386996afb4c5ba0c94aaf5883 (patch) | |
| tree | a7c96227c51e291e4e59eab7a66c6bc223973e06 /minecraft-protocol/src/packets/mod.rs | |
| parent | f64750afdd9b18379f706df66c32806b6d21bbe8 (diff) | |
| download | azalea-drasl-be762fc5d37ba48386996afb4c5ba0c94aaf5883.tar.xz | |
rust is driving me insane
Diffstat (limited to 'minecraft-protocol/src/packets/mod.rs')
| -rw-r--r-- | minecraft-protocol/src/packets/mod.rs | 93 |
1 files changed, 80 insertions, 13 deletions
diff --git a/minecraft-protocol/src/packets/mod.rs b/minecraft-protocol/src/packets/mod.rs index 5fb34743..76f9128e 100644 --- a/minecraft-protocol/src/packets/mod.rs +++ b/minecraft-protocol/src/packets/mod.rs @@ -1,10 +1,12 @@ -mod game; -mod handshake; -mod login; -mod status; +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; use async_trait::async_trait; -use tokio::io::AsyncRead; +use tokio::io::{AsyncRead, BufReader}; + +use crate::connection::PacketFlow; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ConnectionProtocol { @@ -16,24 +18,89 @@ pub enum ConnectionProtocol { pub enum Packet<'a> { // game + // handshake - ClientIntentionPacket(&'a handshake::client_intention_packet::ClientIntentionPacket<'a>), + ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket<'a>), + // login + // status ServerboundStatusRequestPacket( - &'a status::serverbound_status_request_packet::ServerboundStatusRequestPacket, + status::serverbound_status_request_packet::ServerboundStatusRequestPacket, ), - ClientboundStatusRequestPacket( - &'a status::clientbound_status_response_packet::ClientboundStatusRequestPacket, + ClientboundStatusResponsePacket( + status::clientbound_status_response_packet::ClientboundStatusResponsePacket, ), } +// TODO: do all this with macros so it's less repetitive +impl Packet<'_> { + fn get_inner_packet(&self) -> &dyn PacketTrait { + match self { + Packet::ClientIntentionPacket(packet) => packet, + Packet::ServerboundStatusRequestPacket(packet) => packet, + Packet::ClientboundStatusResponsePacket(packet) => packet, + } + } + + pub fn id(&self) -> u32 { + match self { + Packet::ClientIntentionPacket(packet) => 0x00, + Packet::ServerboundStatusRequestPacket(packet) => 0x00, + Packet::ClientboundStatusResponsePacket(packet) => 0x00, + } + } + + /// Read a packet by its id, ConnectionProtocol, and flow + pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>( + id: u32, + protocol: ConnectionProtocol, + flow: PacketFlow, + buf: &mut BufReader<T>, + ) -> Result<Packet<'_>, String> { + match protocol { + ConnectionProtocol::Handshake => match id { + 0x00 => Ok( + handshake::client_intention_packet::ClientIntentionPacket::read(buf).await?, + ), + _ => Err(format!("Unknown packet id: {}", id)), + }, + ConnectionProtocol::Game => Err("Game protocol not implemented yet".to_string()), + ConnectionProtocol::Status => match flow { + PacketFlow::ServerToClient => match id { + 0x00 => Ok( + status::clientbound_status_response_packet::ClientboundStatusResponsePacket + ::read(buf) + .await?, + ), + _ => Err(format!("Unknown packet id: {}", id)), + }, + PacketFlow::ClientToServer => match id { + 0x00 => Ok( + status::serverbound_status_request_packet::ServerboundStatusRequestPacket + ::read(buf) + .await?, + ), + _ => Err(format!("Unknown packet id: {}", id)), + }, + }, + ConnectionProtocol::Login => Err("Login protocol not implemented yet".to_string()), + } + } + + pub fn write(&self, buf: &mut Vec<u8>) { + self.get_inner_packet().write(buf); + } +} + +#[async_trait] pub trait PacketTrait { /// Return a version of the packet that you can actually use for stuff fn get(&self) -> Packet; fn write(&self, buf: &mut Vec<u8>) -> (); - fn parse<T: AsyncRead + std::marker::Unpin>( - buf: &mut T, - // is using a static lifetime here a good idea? idk - ) -> Result<Packet<'_>, String>; + async fn read<T: AsyncRead + std::marker::Unpin + std::marker::Send>( + buf: &mut BufReader<T>, + ) -> Result<Packet<'_>, String> + where + Self: Sized; } |
