From c16d55ccddd741057bf532bd946b2854dc208c65 Mon Sep 17 00:00:00 2001 From: mat Date: Wed, 8 Dec 2021 00:41:42 -0600 Subject: start adding minecraft-chat --- minecraft-protocol/src/connection.rs | 6 +-- minecraft-protocol/src/mc_buf.rs | 48 +++++++++++++++++++--- .../src/packets/client_intention_packet.rs | 4 +- .../packets/clientbound_status_response_packet.rs | 4 +- 4 files changed, 51 insertions(+), 11 deletions(-) (limited to 'minecraft-protocol/src') diff --git a/minecraft-protocol/src/connection.rs b/minecraft-protocol/src/connection.rs index a162bb6b..e0d781c8 100644 --- a/minecraft-protocol/src/connection.rs +++ b/minecraft-protocol/src/connection.rs @@ -64,7 +64,7 @@ impl Connection { // 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); + let mut packet_data = Vec::with_capacity((packet_size - packet_id_size as i32) as usize); buf.read_buf(&mut packet_data).await.unwrap(); println!("packet {:?}", packet_data); @@ -80,7 +80,7 @@ impl Connection { // write the packet id let mut id_and_data_buf = vec![]; - mc_buf::write_varint(&mut id_and_data_buf, packet.get_id()); + mc_buf::write_varint(&mut id_and_data_buf, packet.get_id() as i32); packet.write(&mut id_and_data_buf); // write the packet data @@ -88,7 +88,7 @@ impl Connection { // make a new buffer that has the length at the beginning // and id+data at the end let mut complete_buf: Vec = Vec::new(); - mc_buf::write_varint(&mut complete_buf, id_and_data_buf.len() as u32); + mc_buf::write_varint(&mut complete_buf, id_and_data_buf.len() as i32); complete_buf.append(&mut id_and_data_buf); // finally, write and flush to the stream diff --git a/minecraft-protocol/src/mc_buf.rs b/minecraft-protocol/src/mc_buf.rs index 1e6e5b08..a58905b7 100644 --- a/minecraft-protocol/src/mc_buf.rs +++ b/minecraft-protocol/src/mc_buf.rs @@ -33,14 +33,14 @@ pub fn write_bytes(buf: &mut Vec, bytes: &[u8]) { /// Read a single varint from the reader and return the value, along with the number of bytes read pub async fn read_varint( buf: &mut BufReader, -) -> Result<(u32, u8), String> { +) -> Result<(i32, u8), String> { let mut buffer = [0]; let mut ans = 0; for i in 0..4 { buf.read_exact(&mut buffer) .await .or_else(|_| Err("Invalid VarInt".to_string()))?; - ans |= ((buffer[0] & 0b0111_1111) as u32) << 7 * i; + ans |= ((buffer[0] & 0b0111_1111) as i32) << 7 * i; if buffer[0] & 0b1000_0000 == 0 { return Ok((ans, i + 1)); } @@ -48,14 +48,14 @@ pub async fn read_varint( Ok((ans, 5)) } -pub fn write_varint(buf: &mut Vec, mut value: u32) { +pub fn write_varint(buf: &mut Vec, mut value: i32) { 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); + value = (value >> 7) & (i32::max_value() >> 6); if value != 0 { buffer[0] |= 0b1000_0000; } @@ -104,10 +104,48 @@ pub fn write_utf_with_len(buf: &mut Vec, string: &String, len: usize) { len ); } - write_varint(buf, string.len() as u32); + write_varint(buf, string.len() as i32); write_bytes(buf, string.as_bytes()); } +pub async fn read_utf( + buf: &mut BufReader, + max_length: u32, +) -> Result { + let (length, length_varint_length) = read_varint(buf).await?; + // i don't know why it's multiplied by 4 but it's like that in mojang's code so + if length < 0 { + return Err( + "The received encoded string buffer length is less than zero! Weird string!" + .to_string(), + ); + } + if length as u32 > max_length * 4 { + return Err(format!( + "The received encoded string buffer length is longer than maximum allowed ({} > {})", + length, + max_length * 4 + )); + } + + // this is probably quite inefficient, idk how to do it better + let mut string = String::new(); + let mut buffer = vec![0; length as usize]; + buf.read_exact(&mut buffer) + .await + .or_else(|_| Err("Invalid UTF-8".to_string()))?; + + string.push_str(std::str::from_utf8(&buffer).unwrap()); + if string.len() > length as usize { + return Err(format!( + "The received string length is longer than maximum allowed ({} > {})", + length, max_length + )); + } + + Ok(string) +} + pub fn write_utf(buf: &mut Vec, string: &String) { write_utf_with_len(buf, string, MAX_STRING_LENGTH as usize); } diff --git a/minecraft-protocol/src/packets/client_intention_packet.rs b/minecraft-protocol/src/packets/client_intention_packet.rs index a35e65dc..424c645f 100644 --- a/minecraft-protocol/src/packets/client_intention_packet.rs +++ b/minecraft-protocol/src/packets/client_intention_packet.rs @@ -21,10 +21,10 @@ impl<'a> Packet for ClientIntentionPacket<'a> { // implement "from_reader" for "ClientIntentionPacket" fn write(&self, buf: &mut Vec) { - mc_buf::write_varint(buf, self.protocol_version); + mc_buf::write_varint(buf, self.protocol_version as i32); mc_buf::write_utf(buf, &self.hostname); mc_buf::write_short(buf, self.port); - mc_buf::write_varint(buf, self.intention.clone() as u32); + mc_buf::write_varint(buf, self.intention.clone() as i32); } fn parse(&self, buf: T) -> () {} diff --git a/minecraft-protocol/src/packets/clientbound_status_response_packet.rs b/minecraft-protocol/src/packets/clientbound_status_response_packet.rs index 8baa2a4d..ddca9b1f 100644 --- a/minecraft-protocol/src/packets/clientbound_status_response_packet.rs +++ b/minecraft-protocol/src/packets/clientbound_status_response_packet.rs @@ -4,7 +4,8 @@ use super::Packet; #[derive(Hash)] pub struct ServerboundStatusRequestPacket { - status: ServerStatus, + // status: ServerStatus, + status: String, } // implement "Packet" for "ClientIntentionPacket" @@ -16,6 +17,7 @@ impl Packet for ServerboundStatusRequestPacket { // implement "from_reader" for "ClientIntentionPacket" fn write(&self, _buf: &mut Vec) {} fn parse(&self, buf: T) -> () { + mc_buf::read_utf; // this.status = GsonHelper.fromJson(GSON, friendlyByteBuf.readUtf(32767), ServerStatus.class); } } -- cgit v1.2.3