aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock26
-rw-r--r--azalea-protocol/Cargo.toml3
-rw-r--r--azalea-protocol/packet-macros/Cargo.toml14
-rw-r--r--azalea-protocol/packet-macros/src/lib.rs164
-rw-r--r--azalea-protocol/src/mc_buf.rs14
-rw-r--r--azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs28
-rw-r--r--azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs23
-rw-r--r--azalea-protocol/src/packets/game/mod.rs7
-rw-r--r--azalea-protocol/src/packets/handshake/client_intention_packet.rs60
-rw-r--r--azalea-protocol/src/packets/handshake/mod.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs3
-rw-r--r--azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs3
-rw-r--r--azalea-protocol/src/packets/login/clientbound_hello_packet.rs2
-rw-r--r--azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs3
-rw-r--r--azalea-protocol/src/packets/login/mod.rs2
-rw-r--r--azalea-protocol/src/packets/login/serverbound_hello_packet.rs3
-rw-r--r--azalea-protocol/src/packets/mod.rs8
-rw-r--r--azalea-protocol/src/packets/status/clientbound_status_response_packet.rs4
-rw-r--r--azalea-protocol/src/packets/status/mod.rs2
-rw-r--r--azalea-protocol/src/packets/status/serverbound_status_request_packet.rs2
20 files changed, 285 insertions, 88 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c037630d..eca4d4fa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -118,6 +118,9 @@ dependencies = [
"azalea-nbt",
"byteorder",
"bytes",
+ "num-derive",
+ "num-traits",
+ "packet-macros",
"serde",
"serde_json",
"thiserror",
@@ -173,6 +176,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
+name = "casey"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14"
+dependencies = [
+ "syn",
+]
+
+[[package]]
name = "cast"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -677,6 +689,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
+name = "packet-macros"
+version = "0.1.0"
+dependencies = [
+ "casey",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -755,9 +777,9 @@ checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
[[package]]
name = "proc-macro2"
-version = "1.0.32"
+version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
diff --git a/azalea-protocol/Cargo.toml b/azalea-protocol/Cargo.toml
index c9883195..ff3bd9d4 100644
--- a/azalea-protocol/Cargo.toml
+++ b/azalea-protocol/Cargo.toml
@@ -15,6 +15,9 @@ azalea-core = {path = "../azalea-core"}
azalea-nbt = {path = "../azalea-nbt"}
byteorder = "^1.4.3"
bytes = "^1.1.0"
+num-derive = "^0.3.3"
+num-traits = "^0.2.14"
+packet-macros = {path = "./packet-macros"}
serde = {version = "1.0.130", features = ["serde_derive"]}
serde_json = "^1.0.72"
thiserror = "^1.0.30"
diff --git a/azalea-protocol/packet-macros/Cargo.toml b/azalea-protocol/packet-macros/Cargo.toml
new file mode 100644
index 00000000..5a301756
--- /dev/null
+++ b/azalea-protocol/packet-macros/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+edition = "2021"
+name = "packet-macros"
+version = "0.1.0"
+
+[lib]
+proc-macro = true
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+casey = "^0.3.3"
+proc-macro2 = "^1.0.36"
+quote = "^1.0.10"
+syn = "^1.0.82"
diff --git a/azalea-protocol/packet-macros/src/lib.rs b/azalea-protocol/packet-macros/src/lib.rs
new file mode 100644
index 00000000..470ac4c1
--- /dev/null
+++ b/azalea-protocol/packet-macros/src/lib.rs
@@ -0,0 +1,164 @@
+use quote::{quote, quote_spanned, ToTokens};
+use syn::{self, parse_macro_input, spanned::Spanned, DeriveInput, FieldsNamed};
+
+fn as_packet_derive(
+ input: proc_macro::TokenStream,
+ state: proc_macro2::TokenStream,
+) -> proc_macro::TokenStream {
+ let DeriveInput { ident, data, .. } = parse_macro_input!(input);
+
+ let fields = match data {
+ syn::Data::Struct(syn::DataStruct { fields, .. }) => fields,
+ _ => panic!("#[derive(*Packet)] can only be used on structs"),
+ };
+ let FieldsNamed { named, .. } = match fields {
+ syn::Fields::Named(f) => f,
+ _ => panic!("#[derive(*Packet)] can only be used on structs with named fields"),
+ };
+
+ let write_fields = named
+ .iter()
+ .map(|f| {
+ let field_name = &f.ident;
+ let field_type = &f.ty;
+ // do a different buf.write_* for each field depending on the type
+ // if it's a string, use buf.write_string
+ match field_type {
+ syn::Type::Path(syn::TypePath { path, .. }) => {
+ if path.is_ident("String") {
+ quote! { buf.write_utf(&self.#field_name)?; }
+ } else if path.is_ident("ResourceLocation") {
+ quote! { buf.write_resource_location(&self.#field_name)?; }
+ // i don't know how to do this in a way that isn't terrible
+ } else if path.to_token_stream().to_string() == "Vec < u8 >" {
+ quote! { buf.write_bytes(&self.#field_name)?; }
+ } else if path.is_ident("i32") {
+ // only treat it as a varint if it has the varint attribute
+ if f.attrs.iter().any(|attr| attr.path.is_ident("varint")) {
+ quote! { buf.write_varint(self.#field_name)?; }
+ } else {
+ quote! { buf.write_i32(self.#field_name)?; }
+ }
+ } else if path.is_ident("u32") {
+ if f.attrs.iter().any(|attr| attr.path.is_ident("varint")) {
+ quote! { buf.write_varint(self.#field_name as i32)?; }
+ } else {
+ quote! { buf.write_u32(self.#field_name)?; }
+ }
+ } else if path.is_ident("u16") {
+ quote! { buf.write_short(self.#field_name as i16)?; }
+ } else if path.is_ident("ConnectionProtocol") {
+ quote! { buf.write_varint(self.#field_name.clone() as i32)?; }
+ } else {
+ panic!(
+ "#[derive(*Packet)] doesn't know how to write {}",
+ path.to_token_stream()
+ );
+ }
+ }
+ _ => panic!(
+ "Error writing field {}: {}",
+ field_name.clone().unwrap(),
+ field_type.to_token_stream()
+ ),
+ }
+ })
+ .collect::<Vec<_>>();
+
+ let read_fields = named
+ .iter()
+ .map(|f| {
+ let field_name = &f.ident;
+ let field_type = &f.ty;
+ // do a different buf.write_* for each field depending on the type
+ // if it's a string, use buf.write_string
+ match field_type {
+ syn::Type::Path(syn::TypePath { path, .. }) => {
+ if path.is_ident("String") {
+ quote! { let #field_name = buf.read_utf().await?; }
+ } else if path.is_ident("ResourceLocation") {
+ quote! { let #field_name = buf.read_resource_location().await?; }
+ // i don't know how to do this in a way that isn't terrible
+ } else if path.to_token_stream().to_string() == "Vec < u8 >" {
+ quote! { let #field_name = buf.read_bytes().await?; }
+ } else if path.is_ident("i32") {
+ // only treat it as a varint if it has the varint attribute
+ if f.attrs.iter().any(|a| a.path.is_ident("varint")) {
+ quote! { let #field_name = buf.read_varint().await?; }
+ } else {
+ quote! { let #field_name = buf.read_i32().await?; }
+ }
+ } else if path.is_ident("u32") {
+ if f.attrs.iter().any(|a| a.path.is_ident("varint")) {
+ quote! { let #field_name = buf.read_varint().await? as u32; }
+ } else {
+ quote! { let #field_name = buf.read_u32().await?; }
+ }
+ } else if path.is_ident("u16") {
+ quote! { let #field_name = buf.read_short().await? as u16; }
+ } else if path.is_ident("ConnectionProtocol") {
+ quote! {
+ let #field_name = ConnectionProtocol::from_i32(buf.read_varint().await?)
+ .ok_or_else(|| "Invalid intention".to_string())?;
+ }
+ } else {
+ panic!(
+ "#[derive(*Packet)] doesn't know how to read {}",
+ path.to_token_stream()
+ );
+ }
+ }
+ _ => panic!(
+ "Error reading field {}: {}",
+ field_name.clone().unwrap(),
+ field_type.to_token_stream()
+ ),
+ }
+ })
+ .collect::<Vec<_>>();
+ let read_field_names = named.iter().map(|f| &f.ident).collect::<Vec<_>>();
+
+ let gen = quote! {
+ impl #ident {
+ pub fn get(self) -> #state {
+ #state::#ident(self)
+ }
+
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
+ #(#write_fields)*
+ Ok(())
+ }
+
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut T,
+ ) -> Result<#state, String> {
+ #(#read_fields)*
+ Ok(#ident {
+ #(#read_field_names: #read_field_names),*
+ }.get())
+ }
+ }
+ };
+
+ gen.into()
+}
+
+#[proc_macro_derive(GamePacket, attributes(varint))]
+pub fn derive_game_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ as_packet_derive(input, quote! {crate::packets::game::GamePacket})
+}
+
+#[proc_macro_derive(HandshakePacket, attributes(varint))]
+pub fn derive_handshake_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ as_packet_derive(input, quote! {crate::packets::handshake::HandshakePacket})
+}
+
+#[proc_macro_derive(LoginPacket, attributes(varint))]
+pub fn derive_login_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ as_packet_derive(input, quote! {crate::packets::login::LoginPacket})
+}
+
+#[proc_macro_derive(StatusPacket, attributes(varint))]
+pub fn derive_status_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ as_packet_derive(input, quote! {crate::packets::status::StatusPacket})
+}
diff --git a/azalea-protocol/src/mc_buf.rs b/azalea-protocol/src/mc_buf.rs
index 860f61f2..72583d5a 100644
--- a/azalea-protocol/src/mc_buf.rs
+++ b/azalea-protocol/src/mc_buf.rs
@@ -35,7 +35,7 @@ pub trait Writable {
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_short(&mut self, n: i16) -> Result<(), std::io::Error>;
fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>;
fn write_int(&mut self, n: i32) -> Result<(), std::io::Error>;
fn write_boolean(&mut self, b: bool) -> Result<(), std::io::Error>;
@@ -125,8 +125,8 @@ impl Writable for Vec<u8> {
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)
+ fn write_short(&mut self, n: i16) -> Result<(), std::io::Error> {
+ WriteBytesExt::write_i16::<BigEndian>(self, n)
}
fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> {
@@ -176,6 +176,7 @@ pub trait Readable {
async fn read_nbt(&mut self) -> Result<azalea_nbt::Tag, String>;
async fn read_long(&mut self) -> Result<i64, String>;
async fn read_resource_location(&mut self) -> Result<ResourceLocation, String>;
+ async fn read_short(&mut self) -> Result<i16, String>;
}
#[async_trait]
@@ -334,6 +335,13 @@ where
let location = ResourceLocation::new(&location_string)?;
Ok(location)
}
+
+ async fn read_short(&mut self) -> Result<i16, String> {
+ match AsyncReadExt::read_i16(self).await {
+ Ok(r) => Ok(r),
+ Err(_) => Err("Error reading short".to_string()),
+ }
+ }
}
#[cfg(test)]
diff --git a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs b/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs
index 63047801..24220a83 100644
--- a/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_custom_payload_packet.rs
@@ -1,30 +1,10 @@
-use super::GamePacket;
use crate::mc_buf::{Readable, Writable};
-use azalea_core::{game_type::GameType, resource_location::ResourceLocation};
+use crate::packets::game::GamePacket;
+use azalea_core::resource_location::ResourceLocation;
+use packet_macros::GamePacket;
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, GamePacket)]
pub struct ClientboundCustomPayloadPacket {
pub identifier: ResourceLocation,
pub data: Vec<u8>,
}
-
-impl ClientboundCustomPayloadPacket {
- pub fn get(self) -> GamePacket {
- GamePacket::ClientboundCustomPayloadPacket(self)
- }
-
- pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
- buf.write_resource_location(&self.identifier)?;
- buf.write_bytes(&self.data)?;
- Ok(())
- }
-
- pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut T,
- ) -> Result<GamePacket, String> {
- let identifier = buf.read_resource_location().await?;
- let data = buf.read_bytes().await?;
-
- Ok(ClientboundCustomPayloadPacket { identifier, data }.get())
- }
-}
diff --git a/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs b/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs
index 562f8fc2..f6028e6c 100644
--- a/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_update_view_distance_packet.rs
@@ -2,27 +2,10 @@
use super::GamePacket;
use crate::mc_buf::{Readable, Writable};
+use packet_macros::GamePacket;
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, GamePacket)]
pub struct ClientboundUpdateViewDistancePacket {
+ #[varint]
pub view_distance: i32,
}
-
-impl ClientboundUpdateViewDistancePacket {
- pub fn get(self) -> GamePacket {
- GamePacket::ClientboundUpdateViewDistancePacket(self)
- }
-
- pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
- buf.write_varint(self.view_distance)?;
- Ok(())
- }
-
- pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
- buf: &mut T,
- ) -> Result<GamePacket, String> {
- let view_distance = buf.read_varint().await?;
-
- Ok(ClientboundUpdateViewDistancePacket { view_distance }.get())
- }
-}
diff --git a/azalea-protocol/src/packets/game/mod.rs b/azalea-protocol/src/packets/game/mod.rs
index ab5ca7e8..43b3ca3d 100644
--- a/azalea-protocol/src/packets/game/mod.rs
+++ b/azalea-protocol/src/packets/game/mod.rs
@@ -30,7 +30,9 @@ impl ProtocolPacket for GamePacket {
}
}
- fn write(&self, _buf: &mut Vec<u8>) {}
+ fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
+ Ok(())
+ }
/// Read a packet by its id, ConnectionProtocol, and flow
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
@@ -48,7 +50,8 @@ impl ProtocolPacket for GamePacket {
0x4a => clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket
::read(buf)
.await?,
- _ => return Err(format!("Unknown ServerToClient game packet id: {}", id)),
+ // _ => return Err(format!("Unknown ServerToClient game packet id: {}", id)),
+ _ => panic!("Unknown ServerToClient game packet id: {}", id),
},
PacketFlow::ClientToServer => match id {
// 0x00 => serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
diff --git a/azalea-protocol/src/packets/handshake/client_intention_packet.rs b/azalea-protocol/src/packets/handshake/client_intention_packet.rs
index 939a695e..b3eb8301 100644
--- a/azalea-protocol/src/packets/handshake/client_intention_packet.rs
+++ b/azalea-protocol/src/packets/handshake/client_intention_packet.rs
@@ -1,34 +1,48 @@
+use crate::{
+ mc_buf::{Readable, Writable},
+ packets::ConnectionProtocol,
+};
+use num_traits::FromPrimitive;
+use packet_macros::HandshakePacket;
use std::hash::Hash;
-use crate::{mc_buf::Writable, packets::ConnectionProtocol};
-
-use super::HandshakePacket;
-
-#[derive(Hash, Clone, Debug)]
+#[derive(Hash, Clone, Debug, HandshakePacket)]
pub struct ClientIntentionPacket {
+ #[varint]
pub protocol_version: u32,
pub hostname: String,
pub port: u16,
- /// 1 for status, 2 for login
pub intention: ConnectionProtocol,
}
-impl ClientIntentionPacket {
- pub fn get(self) -> HandshakePacket {
- HandshakePacket::ClientIntentionPacket(self)
- }
+// impl ClientIntentionPacket {
+// pub fn get(self) -> HandshakePacket {
+// HandshakePacket::ClientIntentionPacket(self)
+// }
- pub fn write(&self, buf: &mut Vec<u8>) {
- 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 fn write(&self, buf: &mut Vec<u8>) {
+// 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>(
- _buf: &mut T,
- ) -> Result<HandshakePacket, String> {
- Err("ClientIntentionPacket::parse not implemented".to_string())
- // Ok(ClientIntentionPacket {}.get())
- }
-}
+// pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+// buf: &mut T,
+// ) -> Result<HandshakePacket, String> {
+// let protocol_version = buf.read_varint().await? as u32;
+// let hostname = buf.read_utf().await?;
+// let port = buf.read_short().await? as u16;
+// let intention = buf.read_varint().await?;
+
+// Ok(HandshakePacket::ClientIntentionPacket(
+// ClientIntentionPacket {
+// protocol_version,
+// hostname,
+// port,
+// intention: ConnectionProtocol::from_i32(intention)
+// .ok_or_else(|| "Invalid intention".to_string())?,
+// },
+// ))
+// }
+// }
diff --git a/azalea-protocol/src/packets/handshake/mod.rs b/azalea-protocol/src/packets/handshake/mod.rs
index 1d753645..17465fca 100644
--- a/azalea-protocol/src/packets/handshake/mod.rs
+++ b/azalea-protocol/src/packets/handshake/mod.rs
@@ -22,7 +22,7 @@ impl ProtocolPacket for HandshakePacket {
}
}
- fn write(&self, buf: &mut Vec<u8>) {
+ fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
match self {
HandshakePacket::ClientIntentionPacket(packet) => packet.write(buf),
}
diff --git a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
index 048fa53f..22e58b0d 100644
--- a/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_custom_query_packet.rs
@@ -15,10 +15,11 @@ impl ClientboundCustomQueryPacket {
LoginPacket::ClientboundCustomQueryPacket(self)
}
- pub fn write(&self, buf: &mut Vec<u8>) {
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_varint(self.transaction_id as i32).unwrap();
buf.write_utf(self.identifier.to_string().as_str()).unwrap();
buf.write_bytes(&self.data).unwrap();
+ Ok(())
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
index 1a752c1a..c54aa819 100644
--- a/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_game_profile_packet.rs
@@ -14,11 +14,12 @@ impl ClientboundGameProfilePacket {
LoginPacket::ClientboundGameProfilePacket(self)
}
- pub fn write(&self, buf: &mut Vec<u8>) {
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
for n in self.game_profile.uuid.to_int_array() {
buf.write_int(n as i32).unwrap();
}
buf.write_utf(self.game_profile.name.as_str()).unwrap();
+ Ok(())
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
index e0b865be..9d0cec39 100644
--- a/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_hello_packet.rs
@@ -16,7 +16,7 @@ impl ClientboundHelloPacket {
LoginPacket::ClientboundHelloPacket(self)
}
- pub fn write(&self, _buf: &mut Vec<u8>) {
+ pub fn write(&self, _buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
panic!("ClientboundHelloPacket::write not implemented")
}
diff --git a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
index af355192..a88c6cbf 100644
--- a/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
+++ b/azalea-protocol/src/packets/login/clientbound_login_compression_packet.rs
@@ -14,8 +14,9 @@ impl ClientboundLoginCompressionPacket {
LoginPacket::ClientboundLoginCompressionPacket(self)
}
- pub fn write(&self, buf: &mut Vec<u8>) {
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_varint(self.compression_threshold).unwrap();
+ Ok(())
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/azalea-protocol/src/packets/login/mod.rs b/azalea-protocol/src/packets/login/mod.rs
index 4d490d08..b1f61746 100644
--- a/azalea-protocol/src/packets/login/mod.rs
+++ b/azalea-protocol/src/packets/login/mod.rs
@@ -34,7 +34,7 @@ impl ProtocolPacket for LoginPacket {
}
}
- fn write(&self, buf: &mut Vec<u8>) {
+ fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
match self {
LoginPacket::ClientboundCustomQueryPacket(packet) => packet.write(buf),
LoginPacket::ClientboundGameProfilePacket(packet) => packet.write(buf),
diff --git a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
index 0039cbce..a72480f2 100644
--- a/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
+++ b/azalea-protocol/src/packets/login/serverbound_hello_packet.rs
@@ -14,8 +14,9 @@ impl ServerboundHelloPacket {
LoginPacket::ServerboundHelloPacket(self)
}
- pub fn write(&self, buf: &mut Vec<u8>) {
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
buf.write_utf(&self.username).unwrap();
+ Ok(())
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
diff --git a/azalea-protocol/src/packets/mod.rs b/azalea-protocol/src/packets/mod.rs
index e065b65c..0f1cd2f0 100644
--- a/azalea-protocol/src/packets/mod.rs
+++ b/azalea-protocol/src/packets/mod.rs
@@ -3,13 +3,13 @@ pub mod handshake;
pub mod login;
pub mod status;
-use async_trait::async_trait;
-
use crate::connect::PacketFlow;
+use async_trait::async_trait;
+use num_derive::FromPrimitive;
pub const PROTOCOL_VERSION: u32 = 757;
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash, FromPrimitive)]
pub enum ConnectionProtocol {
Handshake = -1,
Game = 0,
@@ -42,5 +42,5 @@ where
where
Self: Sized;
- fn write(&self, buf: &mut Vec<u8>);
+ fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error>;
}
diff --git a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
index 38270ad1..58f5b701 100644
--- a/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
+++ b/azalea-protocol/src/packets/status/clientbound_status_response_packet.rs
@@ -39,7 +39,9 @@ impl ClientboundStatusResponsePacket {
StatusPacket::ClientboundStatusResponsePacket(Box::new(self))
}
- pub fn write(&self, _buf: &mut Vec<u8>) {}
+ pub fn write(&self, _buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
+ Ok(())
+ }
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
buf: &mut T,
diff --git a/azalea-protocol/src/packets/status/mod.rs b/azalea-protocol/src/packets/status/mod.rs
index 6383bae8..31fedfb9 100644
--- a/azalea-protocol/src/packets/status/mod.rs
+++ b/azalea-protocol/src/packets/status/mod.rs
@@ -29,7 +29,7 @@ impl ProtocolPacket for StatusPacket {
}
}
- fn write(&self, buf: &mut Vec<u8>) {
+ fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
match self {
StatusPacket::ServerboundStatusRequestPacket(packet) => packet.write(buf),
StatusPacket::ClientboundStatusResponsePacket(packet) => packet.write(buf),
diff --git a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
index 3a25ac42..af98f7cb 100644
--- a/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
+++ b/azalea-protocol/src/packets/status/serverbound_status_request_packet.rs
@@ -10,7 +10,7 @@ impl ServerboundStatusRequestPacket {
StatusPacket::ServerboundStatusRequestPacket(self)
}
- pub fn write(&self, _buf: &mut Vec<u8>) {
+ pub fn write(&self, _buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
panic!("ServerboundStatusRequestPacket::write not implemented")
}