use std::net::TcpStream; use anyhow::Result; use craftio_rs::{CraftSyncReader, CraftSyncWriter, CraftTcpConnection}; use mcproto_rs::protocol::HasPacketKind; use mcproto_rs::v1_19_3::{Packet761, Packet761Kind, RawPacket761}; #[macro_export] macro_rules! await_packet { ($packet_type:ident, $conn:expr) => { assert_packet!( $packet_type, $conn.wait_for_packet(Packet761Kind::$packet_type).await? ) }; } #[macro_export] macro_rules! assert_packet { ($packet_type:ident, $obj:expr) => { if let Packet761::$packet_type(packet_data) = $obj { packet_data } else { panic!("Expected packet of type {}", stringify!($packet_type)) } }; ($packet_type:ident, $conn:expr, $errmgs:literal) => { assert_packet!( $packet_type, $conn .read_next_packet() .await? .ok_or(anyhow::anyhow!("Missing packet"))? ) }; } pub struct MinecraftClient { pub connection: CraftTcpConnection, } impl MinecraftClient { pub fn new(connection: CraftTcpConnection) -> Self { Self { connection } } pub fn from_stream(stream: TcpStream) -> Result { Ok(Self { connection: CraftTcpConnection::from_std( stream, mcproto_rs::protocol::PacketDirection::ServerBound, )?, }) } pub async fn read_next_packet(&mut self) -> Result> { if let Some(raw) = self.connection.read_packet::()? { println!("Client -> Server: {:?}", raw); Ok(Some(raw)) } else { Ok(None) } } pub async fn send_packet(&mut self, packet: Packet761) -> Result<()> { println!("Server -> Client: {:?}", packet); self.connection.write_packet(packet)?; Ok(()) } pub async fn wait_for_packet(&mut self, packet_kind: Packet761Kind) -> Result { loop { if let Some(packet) = self.read_next_packet().await? { if packet.kind() == packet_kind { return Ok(packet); } println!("Skipping packet {:?}", packet); } } } }