mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
use az-registry in az-protocol
This commit is contained in:
parent
4301a2f2d4
commit
fcb5bdf042
19 changed files with 143 additions and 50 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -106,6 +106,7 @@ name = "azalea-block"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"azalea-block-macros",
|
||||
"azalea-buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -235,6 +236,7 @@ dependencies = [
|
|||
"async-compression",
|
||||
"async-recursion",
|
||||
"azalea-auth",
|
||||
"azalea-block",
|
||||
"azalea-brigadier",
|
||||
"azalea-buf",
|
||||
"azalea-chat",
|
||||
|
@ -242,6 +244,7 @@ dependencies = [
|
|||
"azalea-crypto",
|
||||
"azalea-nbt",
|
||||
"azalea-protocol-macros",
|
||||
"azalea-registry",
|
||||
"azalea-world",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
|
@ -268,6 +271,7 @@ dependencies = [
|
|||
name = "azalea-registry"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"azalea-buf",
|
||||
"azalea-registry-macros",
|
||||
]
|
||||
|
||||
|
|
|
@ -11,3 +11,4 @@ version = "0.1.0"
|
|||
|
||||
[dependencies]
|
||||
azalea-block-macros = {path = "./azalea-block-macros", version = "^0.1.0"}
|
||||
azalea-buf = {path = "../azalea-buf", version = "^0.1.0"}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
mod behavior;
|
||||
mod blocks;
|
||||
|
||||
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
|
||||
pub use behavior::BlockBehavior;
|
||||
pub use blocks::*;
|
||||
|
||||
use std::mem;
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
mem,
|
||||
};
|
||||
|
||||
impl BlockState {
|
||||
/// 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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -74,8 +74,22 @@ fn create_impl_mcbufreadable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt
|
|||
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! {
|
||||
#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 { .. }) => {
|
||||
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)
|
||||
syn::Data::Enum(syn::DataEnum { variants, .. }) => {
|
||||
// remember whether it's a data variant so we can do an optimization later
|
||||
let mut is_data_enum = false;
|
||||
let mut match_arms = quote!();
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ version = "0.1.0"
|
|||
async-compression = {version = "^0.3.8", features = ["tokio", "zlib"], optional = true}
|
||||
async-recursion = "1.0.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-buf = {path = "../azalea-buf", version = "^0.1.0"}
|
||||
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-nbt = {path = "../azalea-nbt", 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"}
|
||||
byteorder = "^1.4.3"
|
||||
bytes = "^1.1.0"
|
||||
|
|
|
@ -10,9 +10,7 @@ pub struct ClientboundAddEntityPacket {
|
|||
#[var]
|
||||
pub id: u32,
|
||||
pub uuid: Uuid,
|
||||
// TODO: have an entity type enum/struct
|
||||
#[var]
|
||||
pub entity_type: i32,
|
||||
pub entity_type: azalea_registry::EntityType,
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
|
|
|
@ -9,10 +9,14 @@ pub struct ClientboundAwardStatsPacket {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, McBuf)]
|
||||
pub struct Stat {
|
||||
// TODO: make these good enums and stuff
|
||||
#[var]
|
||||
pub stat_type: u32,
|
||||
#[var]
|
||||
pub statistic_id: u32,
|
||||
pub enum Stat {
|
||||
Mined(azalea_registry::Block),
|
||||
Crafted(azalea_registry::Item),
|
||||
Used(azalea_registry::Item),
|
||||
Broken(azalea_registry::Item),
|
||||
PickedUp(azalea_registry::Item),
|
||||
Dropped(azalea_registry::Item),
|
||||
Killed(azalea_registry::EntityType),
|
||||
KilledBy(azalea_registry::EntityType),
|
||||
Custom(azalea_registry::CustomStat),
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundBlockEntityDataPacket {
|
||||
pub pos: BlockPos,
|
||||
// TODO: in vanilla this uses the block entity registry, we should have an enum in azalea-entity for this
|
||||
#[var]
|
||||
pub block_entity_type: u32,
|
||||
pub block_entity_type: azalea_registry::BlockEntityType,
|
||||
pub tag: azalea_nbt::Tag,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use azalea_block::BlockState;
|
||||
use azalea_buf::McBuf;
|
||||
use azalea_core::BlockPos;
|
||||
use azalea_protocol_macros::ClientboundGamePacket;
|
||||
|
@ -7,7 +8,5 @@ pub struct ClientboundBlockEventPacket {
|
|||
pub pos: BlockPos,
|
||||
pub b0: u8,
|
||||
pub b1: u8,
|
||||
// TODO: this is a BlockState, see ClientboundBlockUpdatePacket for more info
|
||||
#[var]
|
||||
pub block: u32,
|
||||
pub block: BlockState,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use azalea_block::BlockState;
|
||||
use azalea_buf::McBuf;
|
||||
use azalea_core::BlockPos;
|
||||
use azalea_protocol_macros::ClientboundGamePacket;
|
||||
|
@ -5,8 +6,5 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundBlockUpdatePacket {
|
||||
pub pos: BlockPos,
|
||||
// TODO: in vanilla this is a BlockState, but here we just have it as a number.
|
||||
// perhaps we could make a crate that only handles block states? right now blockstates are handled in azalea-block
|
||||
#[var]
|
||||
pub block_state: u32,
|
||||
pub block_state: BlockState,
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
|
||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundCooldownPacket {
|
||||
// TODO: make azalea-items or something and use that
|
||||
#[var]
|
||||
pub item: u32,
|
||||
pub item: azalea_registry::Item,
|
||||
#[var]
|
||||
pub duration: u32,
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
pub struct ClientboundOpenScreenPacket {
|
||||
#[var]
|
||||
pub container_id: u32,
|
||||
// TODO: have an enum of this
|
||||
#[var]
|
||||
pub menu_type: u32,
|
||||
pub menu_type: azalea_registry::Menu,
|
||||
pub title: Component,
|
||||
}
|
||||
|
|
|
@ -5,7 +5,5 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
pub struct ClientboundRemoveMobEffectPacket {
|
||||
#[var]
|
||||
pub entity_id: u32,
|
||||
// TODO: have this use an enum
|
||||
#[var]
|
||||
pub effect: u32,
|
||||
pub effect: azalea_registry::MobEffect,
|
||||
}
|
||||
|
|
|
@ -4,9 +4,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
|
||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundSoundEntityPacket {
|
||||
// TODO: sound enum/registry
|
||||
#[var]
|
||||
pub sound: u32,
|
||||
pub sound: azalea_registry::SoundEvent,
|
||||
pub source: SoundSource,
|
||||
#[var]
|
||||
pub id: u32,
|
||||
|
|
|
@ -3,9 +3,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
|
||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundSoundPacket {
|
||||
// TODO: sound enum/registry
|
||||
#[var]
|
||||
pub sound: u32,
|
||||
pub sound: azalea_registry::SoundEvent,
|
||||
pub source: SoundSource,
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
|
|
|
@ -5,9 +5,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
pub struct ClientboundUpdateMobEffectPacket {
|
||||
#[var]
|
||||
pub entity_id: u32,
|
||||
// TODO: have an enum for this
|
||||
#[var]
|
||||
pub effect: u32,
|
||||
pub effect: azalea_registry::MobEffect,
|
||||
pub effect_amplifier: u8,
|
||||
#[var]
|
||||
pub effect_duration_ticks: u32,
|
||||
|
|
|
@ -26,7 +26,6 @@ pub struct ShapelessRecipe {
|
|||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ShapedRecipe {
|
||||
// TODO: make own McBufReadable and McBufWritable for this
|
||||
width: usize,
|
||||
height: usize,
|
||||
group: String,
|
||||
|
|
|
@ -8,4 +8,5 @@ version = "0.1.0"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
azalea-buf = {path = "../azalea-buf", version = "^0.1.0"}
|
||||
azalea-registry-macros = {path = "./azalea-registry-macros", version = "^0.1.0"}
|
||||
|
|
|
@ -67,7 +67,7 @@ pub fn registry(input: TokenStream) -> TokenStream {
|
|||
});
|
||||
}
|
||||
generated.extend(quote! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, azalea_buf::McBuf)]
|
||||
#[repr(u32)]
|
||||
pub enum #name {
|
||||
#enum_items
|
||||
|
@ -75,12 +75,16 @@ pub fn registry(input: TokenStream) -> TokenStream {
|
|||
});
|
||||
|
||||
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! {
|
||||
impl #name {
|
||||
/// Transmutes a u32 to a #name.
|
||||
#[doc = #doc_0]
|
||||
///
|
||||
/// # Safety
|
||||
/// The `id` should be at most #max_id.
|
||||
#[doc = #doc_1]
|
||||
#[inline]
|
||||
pub unsafe fn from_u32_unchecked(id: u32) -> Self {
|
||||
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! {
|
||||
impl TryFrom<u32> for #name {
|
||||
type Error = ();
|
||||
|
||||
/// Safely converts a state id to a block state.
|
||||
#[doc = #doc_0]
|
||||
fn try_from(id: u32) -> Result<Self, Self::Error> {
|
||||
if Self::is_valid_id(id) {
|
||||
Ok(unsafe { Self::from_u32_unchecked(id) })
|
||||
|
|
Loading…
Add table
Reference in a new issue