1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 23:44:38 +00:00

use az-registry in az-protocol

This commit is contained in:
mat 2022-09-05 11:44:48 -05:00
commit fcb5bdf042
19 changed files with 143 additions and 50 deletions

4
Cargo.lock generated
View file

@ -106,6 +106,7 @@ name = "azalea-block"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"azalea-block-macros", "azalea-block-macros",
"azalea-buf",
] ]
[[package]] [[package]]
@ -235,6 +236,7 @@ dependencies = [
"async-compression", "async-compression",
"async-recursion", "async-recursion",
"azalea-auth", "azalea-auth",
"azalea-block",
"azalea-brigadier", "azalea-brigadier",
"azalea-buf", "azalea-buf",
"azalea-chat", "azalea-chat",
@ -242,6 +244,7 @@ dependencies = [
"azalea-crypto", "azalea-crypto",
"azalea-nbt", "azalea-nbt",
"azalea-protocol-macros", "azalea-protocol-macros",
"azalea-registry",
"azalea-world", "azalea-world",
"byteorder", "byteorder",
"bytes", "bytes",
@ -268,6 +271,7 @@ dependencies = [
name = "azalea-registry" name = "azalea-registry"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"azalea-buf",
"azalea-registry-macros", "azalea-registry-macros",
] ]

View file

@ -11,3 +11,4 @@ version = "0.1.0"
[dependencies] [dependencies]
azalea-block-macros = {path = "./azalea-block-macros", version = "^0.1.0"} azalea-block-macros = {path = "./azalea-block-macros", version = "^0.1.0"}
azalea-buf = {path = "../azalea-buf", version = "^0.1.0"}

View file

@ -1,10 +1,13 @@
mod behavior; mod behavior;
mod blocks; mod blocks;
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
pub use behavior::BlockBehavior; pub use behavior::BlockBehavior;
pub use blocks::*; pub use blocks::*;
use std::{
use std::mem; io::{Read, Write},
mem,
};
impl BlockState { impl BlockState {
/// Transmutes a u32 to a block state. /// Transmutes a u32 to a block state.
@ -35,6 +38,20 @@ impl TryFrom<u32> for BlockState {
} }
} }
impl McBufReadable for BlockState {
fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> {
let state_id = u32::var_read_from(buf)?;
Self::try_from(state_id).map_err(|_| BufReadError::UnexpectedEnumVariant {
id: state_id as i32,
})
}
}
impl McBufWritable for BlockState {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
u32::var_write_into(&(*self as u32), buf)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -74,8 +74,22 @@ fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt
variant_discrim += 1; variant_discrim += 1;
} }
} }
let reader = match variant.fields {
syn::Fields::Named(_) => {
panic!("writing named fields in enums is not supported")
}
syn::Fields::Unnamed(_) => quote! {
Ok(Self::#variant_name(azalea_buf::McBufReadable::read_from(buf)?))
},
syn::Fields::Unit => quote! {
Ok(Self::#variant_name)
},
};
match_contents.extend(quote! { match_contents.extend(quote! {
#variant_discrim => Ok(Self::#variant_name), #variant_discrim => {
#reader
},
}); });
} }
@ -141,11 +155,75 @@ fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt
} }
} }
} }
syn::Data::Enum(syn::DataEnum { .. }) => { syn::Data::Enum(syn::DataEnum { variants, .. }) => {
quote! { // remember whether it's a data variant so we can do an optimization later
impl azalea_buf::McBufWritable for #ident { let mut is_data_enum = false;
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { let mut match_arms = quote!();
azalea_buf::McBufVarWritable::var_write_into(&(*self as u32), buf) let mut variant_discrim: u32 = 0;
for variant in variants {
// figure out the discriminant
if let Some(discriminant) = &variant.discriminant {
variant_discrim = match &discriminant.1 {
syn::Expr::Lit(e) => match &e.lit {
syn::Lit::Int(i) => i.base10_parse().unwrap(),
_ => panic!("Error parsing enum discriminant as int"),
},
syn::Expr::Unary(_) => {
panic!("Negative enum discriminants are not supported")
}
_ => {
panic!(
"Error parsing enum discriminant as literal (is {:?})",
discriminant.1
)
}
};
} else {
variant_discrim += 1;
}
match &variant.fields {
syn::Fields::Named(_) => {
panic!("Enum variants with named fields are not supported yet");
}
syn::Fields::Unit => {
let variant_name = &variant.ident;
match_arms.extend(quote! {
Self::#variant_name => {
azalea_buf::McBufVarWritable::var_write_into(&#variant_discrim, buf)?;
}
});
}
syn::Fields::Unnamed(_) => {
is_data_enum = true;
let variant_name = &variant.ident;
match_arms.extend(quote! {
Self::#variant_name(data) => {
azalea_buf::McBufVarWritable::var_write_into(&#variant_discrim, buf)?;
azalea_buf::McBufWritable::write_into(data, buf)?;
}
});
}
}
}
if is_data_enum {
quote! {
impl azalea_buf::McBufWritable for #ident {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
match self {
#match_arms
}
Ok(())
}
}
}
} else {
// optimization: if it doesn't have data we can just do `as u32`
quote! {
impl azalea_buf::McBufWritable for #ident {
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
azalea_buf::McBufVarWritable::var_write_into(&(*self as u32), buf)
}
} }
} }
} }

View file

@ -11,6 +11,7 @@ version = "0.1.0"
async-compression = {version = "^0.3.8", features = ["tokio", "zlib"], optional = true} async-compression = {version = "^0.3.8", features = ["tokio", "zlib"], optional = true}
async-recursion = "1.0.0" async-recursion = "1.0.0"
azalea-auth = {path = "../azalea-auth", version = "^0.1.0"} azalea-auth = {path = "../azalea-auth", version = "^0.1.0"}
azalea-block = {path = "../azalea-block", default-features = false, version = "^0.1.0"}
azalea-brigadier = {path = "../azalea-brigadier", version = "^0.1.0"} azalea-brigadier = {path = "../azalea-brigadier", version = "^0.1.0"}
azalea-buf = {path = "../azalea-buf", version = "^0.1.0"} azalea-buf = {path = "../azalea-buf", version = "^0.1.0"}
azalea-chat = {path = "../azalea-chat", version = "^0.1.1"} azalea-chat = {path = "../azalea-chat", version = "^0.1.1"}
@ -18,6 +19,7 @@ azalea-core = {path = "../azalea-core", optional = true, version = "^0.1.0"}
azalea-crypto = {path = "../azalea-crypto", version = "^0.1.0"} azalea-crypto = {path = "../azalea-crypto", version = "^0.1.0"}
azalea-nbt = {path = "../azalea-nbt", version = "^0.1.0"} azalea-nbt = {path = "../azalea-nbt", version = "^0.1.0"}
azalea-protocol-macros = {path = "./azalea-protocol-macros", version = "^0.1.0"} azalea-protocol-macros = {path = "./azalea-protocol-macros", version = "^0.1.0"}
azalea-registry = {path = "../azalea-registry", version = "^0.1.0"}
azalea-world = {path = "../azalea-world", version = "^0.1.0"} azalea-world = {path = "../azalea-world", version = "^0.1.0"}
byteorder = "^1.4.3" byteorder = "^1.4.3"
bytes = "^1.1.0" bytes = "^1.1.0"

View file

@ -10,9 +10,7 @@ pub struct ClientboundAddEntityPacket {
#[var] #[var]
pub id: u32, pub id: u32,
pub uuid: Uuid, pub uuid: Uuid,
// TODO: have an entity type enum/struct pub entity_type: azalea_registry::EntityType,
#[var]
pub entity_type: i32,
pub x: f64, pub x: f64,
pub y: f64, pub y: f64,
pub z: f64, pub z: f64,

View file

@ -9,10 +9,14 @@ pub struct ClientboundAwardStatsPacket {
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, McBuf)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, McBuf)]
pub struct Stat { pub enum Stat {
// TODO: make these good enums and stuff Mined(azalea_registry::Block),
#[var] Crafted(azalea_registry::Item),
pub stat_type: u32, Used(azalea_registry::Item),
#[var] Broken(azalea_registry::Item),
pub statistic_id: u32, PickedUp(azalea_registry::Item),
Dropped(azalea_registry::Item),
Killed(azalea_registry::EntityType),
KilledBy(azalea_registry::EntityType),
Custom(azalea_registry::CustomStat),
} }

View file

@ -5,8 +5,6 @@ use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundBlockEntityDataPacket { pub struct ClientboundBlockEntityDataPacket {
pub pos: BlockPos, pub pos: BlockPos,
// TODO: in vanilla this uses the block entity registry, we should have an enum in azalea-entity for this pub block_entity_type: azalea_registry::BlockEntityType,
#[var]
pub block_entity_type: u32,
pub tag: azalea_nbt::Tag, pub tag: azalea_nbt::Tag,
} }

View file

@ -1,3 +1,4 @@
use azalea_block::BlockState;
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::BlockPos; use azalea_core::BlockPos;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
@ -7,7 +8,5 @@ pub struct ClientboundBlockEventPacket {
pub pos: BlockPos, pub pos: BlockPos,
pub b0: u8, pub b0: u8,
pub b1: u8, pub b1: u8,
// TODO: this is a BlockState, see ClientboundBlockUpdatePacket for more info pub block: BlockState,
#[var]
pub block: u32,
} }

View file

@ -1,3 +1,4 @@
use azalea_block::BlockState;
use azalea_buf::McBuf; use azalea_buf::McBuf;
use azalea_core::BlockPos; use azalea_core::BlockPos;
use azalea_protocol_macros::ClientboundGamePacket; use azalea_protocol_macros::ClientboundGamePacket;
@ -5,8 +6,5 @@ use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundBlockUpdatePacket { pub struct ClientboundBlockUpdatePacket {
pub pos: BlockPos, pub pos: BlockPos,
// TODO: in vanilla this is a BlockState, but here we just have it as a number. pub block_state: BlockState,
// perhaps we could make a crate that only handles block states? right now blockstates are handled in azalea-block
#[var]
pub block_state: u32,
} }

View file

@ -3,9 +3,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundCooldownPacket { pub struct ClientboundCooldownPacket {
// TODO: make azalea-items or something and use that pub item: azalea_registry::Item,
#[var]
pub item: u32,
#[var] #[var]
pub duration: u32, pub duration: u32,
} }

View file

@ -6,8 +6,6 @@ use azalea_protocol_macros::ClientboundGamePacket;
pub struct ClientboundOpenScreenPacket { pub struct ClientboundOpenScreenPacket {
#[var] #[var]
pub container_id: u32, pub container_id: u32,
// TODO: have an enum of this pub menu_type: azalea_registry::Menu,
#[var]
pub menu_type: u32,
pub title: Component, pub title: Component,
} }

View file

@ -5,7 +5,5 @@ use azalea_protocol_macros::ClientboundGamePacket;
pub struct ClientboundRemoveMobEffectPacket { pub struct ClientboundRemoveMobEffectPacket {
#[var] #[var]
pub entity_id: u32, pub entity_id: u32,
// TODO: have this use an enum pub effect: azalea_registry::MobEffect,
#[var]
pub effect: u32,
} }

View file

@ -4,9 +4,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundEntityPacket { pub struct ClientboundSoundEntityPacket {
// TODO: sound enum/registry pub sound: azalea_registry::SoundEvent,
#[var]
pub sound: u32,
pub source: SoundSource, pub source: SoundSource,
#[var] #[var]
pub id: u32, pub id: u32,

View file

@ -3,9 +3,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)] #[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
pub struct ClientboundSoundPacket { pub struct ClientboundSoundPacket {
// TODO: sound enum/registry pub sound: azalea_registry::SoundEvent,
#[var]
pub sound: u32,
pub source: SoundSource, pub source: SoundSource,
pub x: i32, pub x: i32,
pub y: i32, pub y: i32,

View file

@ -5,9 +5,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
pub struct ClientboundUpdateMobEffectPacket { pub struct ClientboundUpdateMobEffectPacket {
#[var] #[var]
pub entity_id: u32, pub entity_id: u32,
// TODO: have an enum for this pub effect: azalea_registry::MobEffect,
#[var]
pub effect: u32,
pub effect_amplifier: u8, pub effect_amplifier: u8,
#[var] #[var]
pub effect_duration_ticks: u32, pub effect_duration_ticks: u32,

View file

@ -26,7 +26,6 @@ pub struct ShapelessRecipe {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ShapedRecipe { pub struct ShapedRecipe {
// TODO: make own McBufReadable and McBufWritable for this
width: usize, width: usize,
height: usize, height: usize,
group: String, group: String,

View file

@ -8,4 +8,5 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
azalea-buf = {path = "../azalea-buf", version = "^0.1.0"}
azalea-registry-macros = {path = "./azalea-registry-macros", version = "^0.1.0"} azalea-registry-macros = {path = "./azalea-registry-macros", version = "^0.1.0"}

View file

@ -67,7 +67,7 @@ pub fn registry(input: TokenStream) -> TokenStream {
}); });
} }
generated.extend(quote! { generated.extend(quote! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, azalea_buf::McBuf)]
#[repr(u32)] #[repr(u32)]
pub enum #name { pub enum #name {
#enum_items #enum_items
@ -75,12 +75,16 @@ pub fn registry(input: TokenStream) -> TokenStream {
}); });
let max_id = input.items.len() as u32; let max_id = input.items.len() as u32;
let doc_0 = format!("Transmutes a u32 to a {}.", name);
let doc_1 = format!("The `id` should be at most {}.", max_id);
generated.extend(quote! { generated.extend(quote! {
impl #name { impl #name {
/// Transmutes a u32 to a #name. #[doc = #doc_0]
/// ///
/// # Safety /// # Safety
/// The `id` should be at most #max_id. #[doc = #doc_1]
#[inline] #[inline]
pub unsafe fn from_u32_unchecked(id: u32) -> Self { pub unsafe fn from_u32_unchecked(id: u32) -> Self {
std::mem::transmute::<u32, #name>(id) std::mem::transmute::<u32, #name>(id)
@ -93,11 +97,13 @@ pub fn registry(input: TokenStream) -> TokenStream {
} }
}); });
let doc_0 = format!("Safely transmutes a u32 to a {}.", name);
generated.extend(quote! { generated.extend(quote! {
impl TryFrom<u32> for #name { impl TryFrom<u32> for #name {
type Error = (); type Error = ();
/// Safely converts a state id to a block state. #[doc = #doc_0]
fn try_from(id: u32) -> Result<Self, Self::Error> { fn try_from(id: u32) -> Result<Self, Self::Error> {
if Self::is_valid_id(id) { if Self::is_valid_id(id) {
Ok(unsafe { Self::from_u32_unchecked(id) }) Ok(unsafe { Self::from_u32_unchecked(id) })