aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-15 19:23:27 -0600
committermat <github@matdoes.dev>2021-12-15 19:23:27 -0600
commit4794b4f1a0a500fed258863d3d4e7216f67c8639 (patch)
tree3112c9426cc4e637ff80910eef25afff3944d3fb
parentff8e3f2d9e4752cf3ecf8ed80041ab352cceb870 (diff)
downloadazalea-drasl-4794b4f1a0a500fed258863d3d4e7216f67c8639.tar.xz
writing packets is now friendlier
-rw-r--r--minecraft-protocol/src/mc_buf.rs90
-rw-r--r--minecraft-protocol/src/packets/handshake/client_intention_packet.rs10
-rw-r--r--minecraft-protocol/src/packets/login/serverbound_hello_packet.rs4
-rw-r--r--minecraft-protocol/src/write.rs6
4 files changed, 63 insertions, 47 deletions
diff --git a/minecraft-protocol/src/mc_buf.rs b/minecraft-protocol/src/mc_buf.rs
index b42a33bb..54ba1f7d 100644
--- a/minecraft-protocol/src/mc_buf.rs
+++ b/minecraft-protocol/src/mc_buf.rs
@@ -10,51 +10,67 @@ use tokio::io::{AsyncRead, AsyncReadExt};
const MAX_STRING_LENGTH: u16 = 32767;
// const MAX_COMPONENT_STRING_LENGTH: u32 = 262144;
-pub fn write_byte(buf: &mut Vec<u8>, n: u8) {
- WriteBytesExt::write_u8(buf, n).unwrap();
+#[async_trait]
+pub trait Writable {
+ fn write_byte(&mut self, n: u8) -> Result<(), std::io::Error>;
+ fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>;
+ fn write_varint(&mut self, value: i32) -> Result<(), std::io::Error>;
+ fn write_utf_with_len(&mut self, string: &str, len: usize) -> Result<(), std::io::Error>;
+ fn write_utf(&mut self, string: &str) -> Result<(), std::io::Error>;
+ fn write_short(&mut self, n: u16) -> Result<(), std::io::Error>;
+ fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>;
}
-pub fn write_bytes(buf: &mut Vec<u8>, bytes: &[u8]) {
- buf.extend_from_slice(bytes);
-}
+#[async_trait]
+impl Writable for Vec<u8> {
+ fn write_byte(&mut self, n: u8) -> Result<(), std::io::Error> {
+ WriteBytesExt::write_u8(self, n)
+ }
-pub fn write_varint(buf: &mut Vec<u8>, mut value: i32) {
- let mut buffer = [0];
- if value == 0 {
- buf.write_all(&buffer).unwrap();
+ fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> {
+ Ok(self.extend_from_slice(bytes))
}
- while value != 0 {
- buffer[0] = (value & 0b0111_1111) as u8;
- value = (value >> 7) & (i32::max_value() >> 6);
- if value != 0 {
- buffer[0] |= 0b1000_0000;
+
+ fn write_varint(&mut self, mut value: i32) -> Result<(), std::io::Error> {
+ let mut buffer = [0];
+ if value == 0 {
+ self.write_all(&buffer).unwrap();
+ }
+ while value != 0 {
+ buffer[0] = (value & 0b0111_1111) as u8;
+ value = (value >> 7) & (i32::max_value() >> 6);
+ if value != 0 {
+ buffer[0] |= 0b1000_0000;
+ }
+ self.write_all(&buffer)?;
}
- buf.write_all(&buffer).unwrap();
+ Ok(())
}
-}
-pub fn write_utf_with_len(buf: &mut Vec<u8>, string: &str, len: usize) {
- if string.len() > len {
- panic!(
- "String too big (was {} bytes encoded, max {})",
- string.len(),
- len
- );
+ fn write_utf_with_len(&mut self, string: &str, len: usize) -> Result<(), std::io::Error> {
+ if string.len() > len {
+ panic!(
+ "String too big (was {} bytes encoded, max {})",
+ string.len(),
+ len
+ );
+ }
+ self.write_varint(string.len() as i32);
+ self.write_bytes(string.as_bytes())
}
- write_varint(buf, string.len() as i32);
- write_bytes(buf, string.as_bytes());
-}
-pub fn write_utf(buf: &mut Vec<u8>, string: &str) {
- write_utf_with_len(buf, string, MAX_STRING_LENGTH.into());
-}
-pub fn write_short(buf: &mut Vec<u8>, n: u16) {
- WriteBytesExt::write_u16::<BigEndian>(buf, n).unwrap();
-}
+ fn write_utf(&mut self, string: &str) -> Result<(), std::io::Error> {
+ self.write_utf_with_len(string, MAX_STRING_LENGTH.into())
+ }
+
+ fn write_short(&mut self, n: u16) -> Result<(), std::io::Error> {
+ WriteBytesExt::write_u16::<BigEndian>(self, n)
+ }
-pub fn write_byte_array(buf: &mut Vec<u8>, bytes: &[u8]) {
- write_varint(buf, bytes.len() as i32);
- write_bytes(buf, bytes);
+ fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> {
+ self.write_varint(bytes.len() as i32);
+ self.write_bytes(bytes)
+ }
}
#[async_trait]
@@ -159,11 +175,11 @@ mod tests {
#[test]
fn test_write_varint() {
let mut buf = Vec::new();
- write_varint(&mut buf, 123456);
+ buf.write_varint(123456);
assert_eq!(buf, vec![192, 196, 7]);
let mut buf = Vec::new();
- write_varint(&mut buf, 0);
+ buf.write_varint(0);
assert_eq!(buf, vec![0]);
}
diff --git a/minecraft-protocol/src/packets/handshake/client_intention_packet.rs b/minecraft-protocol/src/packets/handshake/client_intention_packet.rs
index 3f7e3b37..868626b3 100644
--- a/minecraft-protocol/src/packets/handshake/client_intention_packet.rs
+++ b/minecraft-protocol/src/packets/handshake/client_intention_packet.rs
@@ -2,7 +2,7 @@ use std::hash::Hash;
use tokio::io::BufReader;
-use crate::{mc_buf, packets::ConnectionProtocol};
+use crate::{mc_buf::Writable, packets::ConnectionProtocol};
use super::HandshakePacket;
@@ -21,10 +21,10 @@ impl ClientIntentionPacket {
}
pub fn write(&self, buf: &mut Vec<u8>) {
- 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 i32);
+ buf.write_varint(self.protocol_version as i32).unwrap();
+ buf.write_utf(&self.hostname).unwrap();
+ buf.write_short(self.port).unwrap();
+ buf.write_varint(self.intention.clone() as i32).unwrap();
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs b/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs
index 69448074..32a6dadc 100644
--- a/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs
+++ b/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs
@@ -1,7 +1,7 @@
use std::hash::Hash;
use tokio::io::BufReader;
-use crate::mc_buf;
+use crate::mc_buf::Writable;
use super::LoginPacket;
@@ -16,7 +16,7 @@ impl ServerboundHelloPacket {
}
pub fn write(&self, buf: &mut Vec<u8>) {
- mc_buf::write_utf(buf, &self.username);
+ buf.write_utf(&self.username).unwrap();
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/minecraft-protocol/src/write.rs b/minecraft-protocol/src/write.rs
index 529bb210..3d8540eb 100644
--- a/minecraft-protocol/src/write.rs
+++ b/minecraft-protocol/src/write.rs
@@ -1,6 +1,6 @@
use tokio::{io::AsyncWriteExt, net::TcpStream};
-use crate::{mc_buf, packets::ProtocolPacket};
+use crate::{mc_buf::Writable, packets::ProtocolPacket};
pub async fn write_packet(packet: impl ProtocolPacket, stream: &mut TcpStream) {
// TODO: implement compression
@@ -10,7 +10,7 @@ pub async fn write_packet(packet: impl ProtocolPacket, stream: &mut TcpStream) {
// write the packet id
let mut id_and_data_buf = vec![];
- mc_buf::write_varint(&mut id_and_data_buf, packet.id() as i32);
+ id_and_data_buf.write_varint(packet.id() as i32);
packet.write(&mut id_and_data_buf);
// write the packet data
@@ -18,7 +18,7 @@ pub async fn write_packet(packet: impl ProtocolPacket, stream: &mut TcpStream) {
// 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 i32);
+ complete_buf.write_varint(id_and_data_buf.len() as i32);
complete_buf.append(&mut id_and_data_buf);
// finally, write and flush to the stream