aboutsummaryrefslogtreecommitdiff
path: root/minecraft-protocol/src
diff options
context:
space:
mode:
Diffstat (limited to 'minecraft-protocol/src')
-rw-r--r--minecraft-protocol/src/connection.rs6
-rw-r--r--minecraft-protocol/src/mc_buf.rs48
-rw-r--r--minecraft-protocol/src/packets/client_intention_packet.rs4
-rw-r--r--minecraft-protocol/src/packets/clientbound_status_response_packet.rs4
4 files changed, 51 insertions, 11 deletions
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<u8> = 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<u8>, 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<T: AsyncRead + std::marker::Unpin>(
buf: &mut BufReader<T>,
-) -> 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<T: AsyncRead + std::marker::Unpin>(
Ok((ans, 5))
}
-pub fn write_varint(buf: &mut Vec<u8>, mut value: u32) {
+pub fn write_varint(buf: &mut Vec<u8>, 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<u8>, 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<T: AsyncRead + std::marker::Unpin>(
+ buf: &mut BufReader<T>,
+ max_length: u32,
+) -> Result<String, String> {
+ 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<u8>, 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<u8>) {
- 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<T: tokio::io::AsyncRead + std::marker::Unpin>(&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<u8>) {}
fn parse<T: tokio::io::AsyncRead + std::marker::Unpin>(&self, buf: T) -> () {
+ mc_buf::read_utf;
// this.status = GsonHelper.fromJson(GSON, friendlyByteBuf.readUtf(32767), ServerStatus.class);
}
}