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/mc_buf.rs | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) (limited to 'minecraft-protocol/src/mc_buf.rs') 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); } -- cgit v1.2.3