diff options
Diffstat (limited to 'minecraft-protocol/src')
| -rw-r--r-- | minecraft-protocol/src/connection.rs | 47 | ||||
| -rw-r--r-- | minecraft-protocol/src/mc_buf.rs | 13 | ||||
| -rw-r--r-- | minecraft-protocol/src/packets/client_intention_packet.rs | 2 | ||||
| -rw-r--r-- | minecraft-protocol/src/packets/mod.rs | 2 | ||||
| -rw-r--r-- | minecraft-protocol/src/packets/serverbound_status_request_packet.rs | 2 |
5 files changed, 41 insertions, 25 deletions
diff --git a/minecraft-protocol/src/connection.rs b/minecraft-protocol/src/connection.rs index b4e3595c..ee03b5e5 100644 --- a/minecraft-protocol/src/connection.rs +++ b/minecraft-protocol/src/connection.rs @@ -1,9 +1,10 @@ +//! Handle sending and receiving packets with a server. + +use crate::packets::ConnectionProtocol; use crate::{mc_buf, packets::Packet, ServerIpAddress}; -use bytes::BytesMut; -use std::io::{Cursor, Read, Write}; use tokio::io::AsyncWriteExt; use tokio::{ - io::{AsyncReadExt, BufReader, BufWriter, SeekFrom, AsyncSeek, AsyncSeekExt}, + io::{AsyncReadExt, BufReader}, net::TcpStream, }; @@ -13,6 +14,7 @@ pub enum PacketFlow { } pub struct Connection { + pub state: ConnectionProtocol, pub flow: PacketFlow, /// The buffered writer pub stream: TcpStream, @@ -33,6 +35,7 @@ impl Connection { .expect("Error enabling tcp_nodelay"); Ok(Connection { + state: ConnectionProtocol::Handshaking, flow: PacketFlow::ClientToServer, stream, }) @@ -45,38 +48,38 @@ impl Connection { // 3. read the rest of the packet and add it to the cursor // the first thing minecraft sends us is the length as a varint, which can be up to 5 bytes long - let mut buf = BufReader::with_capacity(5 * 1024, &mut self.stream); + let mut buf = BufReader::with_capacity(4 * 1024 * 1024, &mut self.stream); + println!("reading length varint"); let (packet_size, packet_size_varint_size) = mc_buf::read_varint(&mut buf).await?; - // then, minecraft tells us the packet id as a single byte - let packet_id = mc_buf::read_byte(&mut buf).await?; - - // read the rest of the packet - let mut packet_data = Vec::with_capacity( - ( - packet_size // the total size of the packet - - 1 // we just read the packet id, so we don't read that byte again - ) as usize); + // then, minecraft tells us the packet id as a varint + println!("reading id varint"); + let (packet_id, packet_id_size) = mc_buf::read_varint(&mut buf).await?; + + // if we recognize the packet id, parse it + + // TODO + + // otherwise, read the rest of the packet and throw it away + let mut packet_data = Vec::with_capacity((packet_size - packet_id_size as u32) as usize); buf.read_buf(&mut packet_data).await.unwrap(); - println!("packet {}", packet_id); - // println!( - // "packet id {}: {}", - // packet_id, - // String::from_utf8(packet_data.clone()).unwrap() - // ); + println!("packet {:?}", packet_data); Ok(()) } /// Write a packet to the server pub async fn send_packet(&mut self, packet: &dyn Packet) { + // TODO: implement compression + // packet structure: - // length + id + data + // length (varint) + id (varint) + data // write the packet id - let mut id_and_data_buf = vec![packet.get_id()]; + let mut id_and_data_buf = vec![]; + mc_buf::write_varint(&mut id_and_data_buf, packet.get_id()); + packet.write(&mut id_and_data_buf); // write the packet data - packet.write(&mut id_and_data_buf); // make a new buffer that has the length at the beginning // and id+data at the end diff --git a/minecraft-protocol/src/mc_buf.rs b/minecraft-protocol/src/mc_buf.rs index f657626f..1e6e5b08 100644 --- a/minecraft-protocol/src/mc_buf.rs +++ b/minecraft-protocol/src/mc_buf.rs @@ -50,6 +50,9 @@ pub async fn read_varint<T: AsyncRead + std::marker::Unpin>( pub fn write_varint(buf: &mut Vec<u8>, mut value: u32) { let mut buffer = [0]; + if value == 0 { + buf.write(&buffer).unwrap(); + } while value != 0 { buffer[0] = (value & 0b0111_1111) as u8; value = (value >> 7) & (u32::max_value() >> 6); @@ -68,12 +71,22 @@ mod tests { let mut buf = Vec::new(); write_varint(&mut buf, 123456); assert_eq!(buf, vec![192, 196, 7]); + + let mut buf = Vec::new(); + write_varint(&mut buf, 0); + assert_eq!(buf, vec![0]); } #[tokio::test] async fn test_read_varint() { let mut buf = BufReader::new(Cursor::new(vec![192, 196, 7])); assert_eq!(read_varint(&mut buf).await.unwrap(), (123456, 3)); + + let mut buf = BufReader::new(Cursor::new(vec![0])); + assert_eq!(read_varint(&mut buf).await.unwrap(), (0, 1)); + + let mut buf = BufReader::new(Cursor::new(vec![1])); + assert_eq!(read_varint(&mut buf).await.unwrap(), (1, 1)); } #[tokio::test] diff --git a/minecraft-protocol/src/packets/client_intention_packet.rs b/minecraft-protocol/src/packets/client_intention_packet.rs index 80c9ce66..90574038 100644 --- a/minecraft-protocol/src/packets/client_intention_packet.rs +++ b/minecraft-protocol/src/packets/client_intention_packet.rs @@ -15,7 +15,7 @@ pub struct ClientIntentionPacket<'a> { // implement "Packet" for "ClientIntentionPacket" impl<'a> Packet for ClientIntentionPacket<'a> { - fn get_id(&self) -> u8 { + fn get_id(&self) -> u32 { 0x00 } diff --git a/minecraft-protocol/src/packets/mod.rs b/minecraft-protocol/src/packets/mod.rs index b8372ccd..6a053124 100644 --- a/minecraft-protocol/src/packets/mod.rs +++ b/minecraft-protocol/src/packets/mod.rs @@ -13,7 +13,7 @@ pub enum ConnectionProtocol { pub trait Packet { /// Get the id of the packet, this is always a byte. - fn get_id(&self) -> u8; + fn get_id(&self) -> u32; fn write(&self, friendly_byte_buf: &mut Vec<u8>) -> (); } diff --git a/minecraft-protocol/src/packets/serverbound_status_request_packet.rs b/minecraft-protocol/src/packets/serverbound_status_request_packet.rs index 54e2a614..94b7bbee 100644 --- a/minecraft-protocol/src/packets/serverbound_status_request_packet.rs +++ b/minecraft-protocol/src/packets/serverbound_status_request_packet.rs @@ -7,7 +7,7 @@ pub struct ServerboundStatusRequestPacket {} // implement "Packet" for "ClientIntentionPacket" impl Packet for ServerboundStatusRequestPacket { - fn get_id(&self) -> u8 { + fn get_id(&self) -> u32 { 0x00 } |
