pub mod game; pub mod handshake; pub mod login; pub mod status; use crate::{ connect::PacketFlow, mc_buf::{McBufReadable, McBufWritable, Readable, Writable}, }; use async_trait::async_trait; use num_derive::FromPrimitive; use num_traits::FromPrimitive; use tokio::io::AsyncRead; pub const PROTOCOL_VERSION: u32 = 757; #[derive(Debug, Clone, PartialEq, Eq, Hash, FromPrimitive)] pub enum ConnectionProtocol { Handshake = -1, Game = 0, Status = 1, Login = 2, } #[derive(Clone, Debug)] pub enum Packet { Game(game::GamePacket), Handshake(handshake::HandshakePacket), Login(login::LoginPacket), Status(Box), } /// An enum of packets for a certain protocol #[async_trait] pub trait ProtocolPacket where Self: Sized, { fn id(&self) -> u32; /// Read a packet by its id, ConnectionProtocol, and flow async fn read( id: u32, flow: &PacketFlow, buf: &mut T, ) -> Result where Self: Sized; fn write(&self, buf: &mut Vec) -> Result<(), std::io::Error>; } #[async_trait] impl McBufReadable for ConnectionProtocol { async fn read_into(buf: &mut R) -> Result where R: AsyncRead + std::marker::Unpin + std::marker::Send, { ConnectionProtocol::from_i32(buf.read_varint().await?) .ok_or_else(|| "Invalid intention".to_string()) } } impl McBufWritable for ConnectionProtocol { fn write_into(&self, buf: &mut Vec) -> Result<(), std::io::Error> { buf.write_varint(self.clone() as i32) } }