aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Sacchini <joey@sacchini.net>2020-10-20 18:20:45 -0400
committerJoey Sacchini <joey@sacchini.net>2020-10-20 18:20:45 -0400
commit9facbf7d8a9c00b2413be325b23aeed786d7a7c1 (patch)
treef5260368a63f4202523ef4ab54c69eab55814220
parentfc08a93b6109373652d6775fe1bfb7d18cdb7575 (diff)
downloadmcproto-rs-9facbf7d8a9c00b2413be325b23aeed786d7a7c1.tar.gz
mcproto-rs-9facbf7d8a9c00b2413be325b23aeed786d7a7c1.tar.bz2
mcproto-rs-9facbf7d8a9c00b2413be325b23aeed786d7a7c1.zip
lots of macro and type refactoring to simplify common patterns such as: position/location/rotation, counted array types (macro -> generics), rename some macros, and use macros to implement primitives (and other things in types.rs inc: VarInt/VarNum)
-rw-r--r--Cargo.lock19
-rw-r--r--Cargo.toml1
-rw-r--r--src/byte_order.rs8
-rw-r--r--src/protocol.rs245
-rw-r--r--src/serialize.rs4
-rw-r--r--src/test_macros.rs2
-rw-r--r--src/types.rs716
-rw-r--r--src/v1_15_2.rs578
8 files changed, 710 insertions, 863 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0b731db..992e4cd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -74,7 +74,6 @@ version = "0.2.0"
dependencies = [
"base64",
"flate2",
- "paste",
"rand",
"serde",
"serde_json",
@@ -91,12 +90,6 @@ dependencies = [
]
[[package]]
-name = "paste"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0520af26d4cf99643dbbe093a61507922b57232d9978d8491fdc8f7b44573c8c"
-
-[[package]]
name = "ppv-lite86"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -169,18 +162,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
+checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
+checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote",
@@ -200,9 +193,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.44"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd"
+checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index 5d6623c..c98eab0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,7 +10,6 @@ keywords = ["minecraft", "games", "protocol", "serialziers", "deserializers", "p
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
base64 = { version = "0.12.3", default-features = false, features = ["alloc"] }
rand = { version = "0.7", optional = true }
-paste = "1.0.1"
[dependencies.serde]
version = "1.0.116"
diff --git a/src/byte_order.rs b/src/byte_order.rs
index f1c40e3..2f65ca8 100644
--- a/src/byte_order.rs
+++ b/src/byte_order.rs
@@ -53,6 +53,10 @@ pub trait ByteOrder {
Ok(Self::read_ushort(data)?.map(move |data| data as i16))
}
+ fn write_ubyte(v: u8) -> [u8; 1] {
+ [v]
+ }
+
fn read_ubyte(data: &[u8]) -> DeserializeResult<u8> {
match data.split_first() {
Some((byte, rest)) => Deserialized::ok(*byte, rest),
@@ -60,6 +64,10 @@ pub trait ByteOrder {
}
}
+ fn write_byte(v: i8) -> [u8; 1] {
+ [v as u8]
+ }
+
fn read_byte(data: &[u8]) -> DeserializeResult<i8> {
Ok(Self::read_ubyte(data)?.map(move |b| b as i8))
}
diff --git a/src/protocol.rs b/src/protocol.rs
index fb2c1fb..9781bb2 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -87,19 +87,7 @@ macro_rules! as_item {
}
#[macro_export]
-macro_rules! __protocol_body_serialize_def_helper {
- ($to: ident, $slf: ident, $fieldn: ident, $($field_rest: ident),+) => {
- $to.serialize_other(&$slf.$fieldn)?;
- $crate::__protocol_body_serialize_def_helper!($to, $slf, $($field_rest),+);
- };
-
- ( $to: ident, $slf: ident, $fieldn: ident ) => {
- $to.serialize_other(&$slf.$fieldn)
- };
-}
-
-#[macro_export]
-macro_rules! __protocol_body_def_helper {
+macro_rules! proto_struct {
($bodyt: ident { }) => {
#[derive(Debug, Clone, PartialEq, Default)]
pub struct $bodyt;
@@ -123,15 +111,17 @@ macro_rules! __protocol_body_def_helper {
}
}
};
- ($bodyt: ident { $($fname: ident: $ftyp: ty ),+ }) => {
+ ($bodyt: ident $(<$($g: ident),*>)? {
+ $($fname: ident: $ftyp: ty ),+
+ }) => {
$crate::as_item! {
#[derive(Debug, Clone, PartialEq)]
- pub struct $bodyt {
+ pub struct $bodyt$(<$($g),*> where $($g: alloc::fmt::Debug + Clone + PartialEq),*)? {
$(pub $fname: $ftyp),+
}
}
- impl Serialize for $bodyt {
+ impl$(<$($g),*>)? Serialize for $bodyt$(<$($g),*> where $($g: Serialize + alloc::fmt::Debug + Clone + PartialEq),*)? {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
$(
to.serialize_other(&self.$fname)?;
@@ -140,7 +130,7 @@ macro_rules! __protocol_body_def_helper {
}
}
- impl Deserialize for $bodyt {
+ impl$(<$($g),*>)? Deserialize for $bodyt$(<$($g),*> where $($g: Deserialize + alloc::fmt::Debug + Clone + PartialEq),*)? {
fn mc_deserialize(_rest: &[u8]) -> DeserializeResult<'_, Self> {
$(let Deserialized{ value: $fname, data: _rest } = <$ftyp>::mc_deserialize(_rest)?;)+
@@ -148,8 +138,23 @@ macro_rules! __protocol_body_def_helper {
}
}
+ #[allow(unused_parens)]
+ impl$(<$($g),*>)? From<($($ftyp),+)> for $bodyt$(<$($g),*>)? $(where $($g: alloc::fmt::Debug + Clone + PartialEq),*)? {
+ fn from(other: ($($ftyp),+)) -> Self {
+ let ($($fname),+) = other;
+ Self { $($fname),+ }
+ }
+ }
+
+ #[allow(unused_parens)]
+ impl$(<$($g),*>)? From<$bodyt$(<$($g),*>)?> for ($($ftyp),+) $(where $($g: alloc::fmt::Debug + Clone + PartialEq),*)? {
+ fn from(other: $bodyt$(<$($g),*>)?) -> Self {
+ ($(other.$fname),+)
+ }
+ }
+
#[cfg(all(test, feature = "std"))]
- impl TestRandom for $bodyt {
+ impl$(<$($g),*>)? TestRandom for $bodyt$(<$($g),*> where $($g: TestRandom + alloc::fmt::Debug + Clone + PartialEq),*)? {
fn test_gen_random() -> Self {
Self{ $($fname: <$ftyp>::test_gen_random()),+ }
}
@@ -159,7 +164,11 @@ macro_rules! __protocol_body_def_helper {
#[macro_export]
macro_rules! define_protocol {
- ($packett: ident, $rawpackett: ident, $rawdt: ident, $directiont: ident, $statet: ident, $idt: ident, $idi: ident => { $($nam: ident, $id: literal, $state: ident, $direction: ident => $body: ident { $($fnam: ident: $ftyp: ty),* }),*}) => {
+ ($packett: ident, $rawpackett: ident, $rawdt: ident, $directiont: ident, $statet: ident, $idt: ident, $idi: ident => {
+ $($nam: ident, $id: literal, $state: ident, $direction: ident => $body: ident {
+ $($fnam: ident: $ftyp: ty),* }),*
+ }
+ ) => {
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct $idi {
pub id: $idt,
@@ -358,15 +367,15 @@ macro_rules! define_protocol {
}
}
- $($crate::__protocol_body_def_helper!($body { $($fnam: $ftyp),* });)*
+ $($crate::proto_struct!($body { $($fnam: $ftyp),* });)*
};
}
#[macro_export]
-macro_rules! count_num {
- () => { 0 };
- ($item: tt) => { 1 };
- ($item: tt, $($rest: tt),+) => { 1 + count_num!($($rest),+) }
+macro_rules! strip_plus {
+ (+ $($rest: tt)*) => {
+ $($rest)*
+ }
}
#[macro_export]
@@ -415,6 +424,10 @@ macro_rules! proto_enum_with_type {
}
impl $typname {
+ pub const fn variant_count() -> usize {
+ crate::strip_plus!($(+ crate::instead_of_ident!($bval, 1))+)
+ }
+
pub fn deserialize_with_id<'a>(id: $typ, data: &'a[u8]) -> DeserializeResult<'a, Self> {
match id.into() {
$($bval => proto_enum_deserialize_variant!(data, $typname::$nam $(($bod))?)),*,
@@ -450,7 +463,10 @@ macro_rules! proto_enum_with_type {
#[cfg(all(test, feature = "std"))]
impl TestRandom for $typname {
fn test_gen_random() -> Self {
- let mut idx: usize = (rand::random::<usize>() % (count_num!($($bval),+))) + 1;
+ let mut rng = rand::thread_rng();
+ use rand::distributions::Distribution;
+ let distr = rand::distributions::Uniform::new(1, Self::variant_count() + 1);
+ let mut idx: usize = distr.sample(&mut rng);
$(
idx -= 1;
if idx == 0 {
@@ -511,6 +527,10 @@ macro_rules! proto_str_enum {
}
impl $typname {
+ pub const fn variant_count() -> usize {
+ crate::strip_plus!($(+ crate::instead_of_ident!($sval, 1))+)
+ }
+
pub fn name(&self) -> &str {
match self {
$($typname::$nam$((instead_of_ident!($bod, _)))? => $sval),+,
@@ -554,7 +574,10 @@ macro_rules! proto_str_enum {
#[cfg(all(test, feature = "std"))]
impl TestRandom for $typname {
fn test_gen_random() -> Self {
- let mut idx: usize = (rand::random::<usize>() % (count_num!($($nam),+))) + 1;
+ let mut rng = rand::thread_rng();
+ use rand::distributions::Distribution;
+ let distr = rand::distributions::Uniform::new(1, Self::variant_count() + 1);
+ let mut idx: usize = distr.sample(&mut rng);
$(
idx -= 1;
if idx == 0 {
@@ -569,38 +592,22 @@ macro_rules! proto_str_enum {
#[macro_export]
macro_rules! proto_byte_flag {
- ($typname: ident, $($bval: literal :: $nam: ident),*) => {
+ ($typname: ident, $($bval: literal :: $isnam: ident $setnam: ident),*) => {
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub struct $typname(pub u8);
impl $typname {
- $(paste::paste! {
- pub fn [<is_ $nam>](&self) -> bool {
- self.0 & $bval != 0
- }
- })*
-
- $(paste::paste! {
- pub fn [<set_ $nam>](&mut self, value: bool) {
- if value {
- self.0 |= $bval;
- } else {
- self.0 ^= $bval;
- }
- }
- })*
-
- $(paste::paste! {
- pub fn [<with_ $nam>](mut self, value: bool) -> Self {
- if value {
- self.0 |= $bval;
- } else {
- self.0 ^= $bval;
- }
+ $(pub fn $isnam(&self) -> bool {
+ self.0 & $bval != 0
+ }
- self
+ pub fn $setnam(&mut self, value: bool) {
+ if value {
+ self.0 |= $bval;
+ } else {
+ self.0 ^= $bval;
}
- })*
+ })+
}
impl Serialize for $typname {
@@ -619,137 +626,11 @@ macro_rules! proto_byte_flag {
impl TestRandom for $typname {
fn test_gen_random() -> Self {
let mut out = <$typname>::default();
- $(paste::paste! {
- out.[<set_ $nam>](rand::random::<bool>());
- })+
+ $(
+ out.$setnam(rand::random::<bool>());
+ )+
out
}
}
}
-}
-
-#[macro_export]
-macro_rules! counted_array_type {
- ($name: ident, $countert: ty, $tousize_fn: ident, $fromusize_fn: ident) => {
- #[derive(Debug, Clone, PartialEq)]
- pub struct $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- pub data: Vec<T>,
- }
-
- impl<T> Serialize for $name<T>
- where
- T: Serialize + Debug + Clone + PartialEq,
- {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let count: $countert = $fromusize_fn(self.data.len());
- to.serialize_other(&count)?;
-
- for entry in &self.data {
- to.serialize_other(entry)?;
- }
-
- Ok(())
- }
- }
-
- impl<T> Deserialize for $name<T>
- where
- T: Deserialize + Debug + Clone + PartialEq,
- {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- let Deserialized {
- value: raw_count,
- mut data,
- } = <$countert>::mc_deserialize(data)?;
- let count: usize = $tousize_fn(raw_count);
-
- let mut out = Vec::with_capacity(count);
- for _ in 0..count {
- let Deserialized {
- value: next,
- data: rest,
- } = T::mc_deserialize(data)?;
- data = rest;
- out.push(next);
- }
-
- Deserialized::ok(Self { data: out }, data)
- }
- }
-
- impl<T> Into<Vec<T>> for $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- fn into(self) -> Vec<T> {
- self.data
- }
- }
-
- impl<T> From<Vec<T>> for $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- fn from(data: Vec<T>) -> Self {
- Self { data }
- }
- }
-
- impl<'a, T> IntoIterator for &'a mut $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- type Item = &'a mut T;
- type IntoIter = alloc::slice::IterMut<'a, T>;
-
- fn into_iter(self) -> Self::IntoIter {
- let data = &mut self.data;
- data.iter_mut()
- }
- }
-
- impl<'a, T> IntoIterator for &'a $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- type Item = &'a T;
- type IntoIter = alloc::slice::Iter<'a, T>;
-
- fn into_iter(self) -> Self::IntoIter {
- let data = &self.data;
- data.iter()
- }
- }
-
- impl<T> IntoIterator for $name<T>
- where
- T: Debug + Clone + PartialEq,
- {
- type Item = T;
- type IntoIter = alloc::vec::IntoIter<T>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.data.into_iter()
- }
- }
-
- #[cfg(all(test, feature = "std"))]
- impl<T> TestRandom for $name<T>
- where
- T: TestRandom + Debug + Clone + PartialEq,
- {
- fn test_gen_random() -> Self {
- let elem_count: usize = rand::random::<usize>() % 32;
- let mut out = Vec::with_capacity(elem_count);
- for _ in 0..elem_count {
- out.push(T::test_gen_random());
- }
-
- Self { data: out }
- }
- }
- };
-}
+} \ No newline at end of file
diff --git a/src/serialize.rs b/src/serialize.rs
index c23ea09..9817797 100644
--- a/src/serialize.rs
+++ b/src/serialize.rs
@@ -1,4 +1,4 @@
-use alloc::{string::String, fmt, vec};
+use alloc::{string::String, fmt};
pub enum SerializeErr {
FailedJsonEncode(String),
@@ -34,7 +34,7 @@ pub trait Serializer: Sized {
fn serialize_bytes(&mut self, data: &[u8]) -> SerializeResult;
fn serialize_byte(&mut self, byte: u8) -> SerializeResult {
- self.serialize_bytes(vec![byte].as_slice())
+ self.serialize_bytes(&[byte])
}
fn serialize_other<S: Serialize>(&mut self, other: &S) -> SerializeResult {
diff --git a/src/test_macros.rs b/src/test_macros.rs
index 1ab1716..1eeddb9 100644
--- a/src/test_macros.rs
+++ b/src/test_macros.rs
@@ -4,7 +4,7 @@ macro_rules! packet_test_cases {
($pnam: ident, $varnam: ident, $bodnam: ident, $testnam: ident, $benchnams: ident, $benchnamd: ident) => {
#[test]
fn $testnam() {
- for k in 0..10 {
+ for k in 0..50 {
let packet = $pnam::$varnam($bodnam::test_gen_random());
if k == 0 {
println!("{:?}", packet);
diff --git a/src/types.rs b/src/types.rs
index ac2334c..f9b37e1 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -35,301 +35,148 @@ impl TestRandom for bool {
}
}
-// u8
-impl Serialize for u8 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_byte(*self)
- }
-}
-
-impl Deserialize for u8 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_ubyte(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for u8 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// i8
-impl Serialize for i8 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_byte(*self as u8)
- }
-}
-
-impl Deserialize for i8 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_byte(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for i8 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// u16
-impl Serialize for u16 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_ushort(*self);
- to.serialize_bytes(&data)
- }
-}
-
-impl Deserialize for u16 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_ushort(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for u16 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// i16
-impl Serialize for i16 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_short(*self);
- to.serialize_bytes(&data)
- }
-}
-
-impl Deserialize for i16 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_short(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for i16 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// int
-impl Serialize for i32 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_int(*self);
- to.serialize_bytes(&data[..])
- }
-}
-
-impl Deserialize for i32 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_int(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for i32 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// long
-impl Serialize for i64 {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_long(*self);
- to.serialize_bytes(&data[..])
- }
-}
-
-impl Deserialize for i64 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_long(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for i64 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// float
-impl Serialize for f32 {
- //noinspection ALL
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_float(*self);
- to.serialize_bytes(&data[..])
- }
-}
-
-impl Deserialize for f32 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_float(data)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for f32 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
-
-// double
-impl Serialize for f64 {
- //noinspection ALL
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let data = ProtoByteOrder::write_double(*self);
- to.serialize_bytes(&data[..])
- }
-}
+macro_rules! def_primitive {
+ ($nam: ty, $read: ident, $write: ident) => {
+ impl Serialize for $nam {
+ fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
+ let data = ProtoByteOrder::$write(*self);
+ to.serialize_bytes(&data)
+ }
+ }
-impl Deserialize for f64 {
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- ProtoByteOrder::read_double(data)
- }
-}
+ impl Deserialize for $nam {
+ fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
+ ProtoByteOrder::$read(data)
+ }
+ }
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for f64 {
- fn test_gen_random() -> Self {
- rand::random()
- }
-}
+ #[cfg(all(test, feature = "std"))]
+ impl TestRandom for $nam {
+ fn test_gen_random() -> Self {
+ rand::random()
+ }
+ }
+ };
+}
+
+def_primitive!(u8, read_ubyte, write_ubyte);
+def_primitive!(i8, read_byte, write_byte);
+def_primitive!(u16, read_ushort, write_ushort);
+def_primitive!(i16, read_short, write_short);
+def_primitive!(u32, read_uint, write_uint);
+def_primitive!(i32, read_int, write_int);
+def_primitive!(u64, read_ulong, write_ulong);
+def_primitive!(i64, read_long, write_long);
+def_primitive!(u128, read_u2long, write_u2long);
+def_primitive!(i128, read_2long, write_2long);
+def_primitive!(f32, read_float, write_float);
+def_primitive!(f64, read_double, write_double);
// VAR INT AND VAR LONG
-const VAR_INT_BYTES: usize = 5;
-const VAR_LONG_BYTES: usize = 10;
-
-#[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Default, Hash, Ord, Eq)]
-pub struct VarInt(pub i32);
-
-impl Serialize for VarInt {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let mut data = [0u8; VAR_INT_BYTES];
- to.serialize_bytes(serialize_var_num((self.0 as u32) as u64, &mut data))
- }
-}
-
-impl Deserialize for VarInt {
- fn mc_deserialize(orig_data: &[u8]) -> DeserializeResult<Self> {
- Ok(deserialize_var_num(orig_data, VAR_INT_BYTES)?.map(move |v| VarInt(v as i32)))
- }
-}
-
-impl Into<i32> for VarInt {
- fn into(self) -> i32 {
- self.0
- }
-}
-
-impl From<i32> for VarInt {
- fn from(v: i32) -> Self {
- Self(v)
- }
-}
-
-impl Into<usize> for VarInt {
- fn into(self) -> usize {
- self.0 as usize
- }
-}
-
-impl From<usize> for VarInt {
- fn from(v: usize) -> Self {
- Self(v as i32)
- }
-}
-
-impl fmt::Display for VarInt {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "VarInt({})", self.0)
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for VarInt {
- fn test_gen_random() -> Self {
- let out: i32 = rand::random();
- Self(out)
- }
-}
+macro_rules! def_varnum {
+ ($nam: ident, $data_type: ty, $working_type: ty, $max_bytes: literal) => {
+ #[derive(Copy, Clone, PartialOrd, PartialEq, Default, Hash, Ord, Eq)]
+ pub struct $nam(pub $data_type);
+
+ impl Serialize for $nam {
+ fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
+ let mut out = [0u8; $max_bytes];
+ let mut v: $working_type = self.0 as $working_type;
+ let mut byte_idx = 0;
+ let mut has_more = true;
+ while has_more {
+ if byte_idx == out.len() {
+ panic!("tried to write too much data for {}", stringify!($nam));
+ }
+
+ let mut v_byte = (v & 0x7F) as u8;
+ v >>= 7;
+ has_more = v != 0;
+ if has_more {
+ v_byte |= 0x80;
+ }
+
+ out[byte_idx] = v_byte;
+ byte_idx += 1;
+ }
+
+ to.serialize_bytes(&out[..byte_idx])
+ }
+ }
-#[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Default, Hash, Ord, Eq)]
-pub struct VarLong(pub i64);
+ impl Deserialize for $nam {
+ fn mc_deserialize(orig_data: &[u8]) -> DeserializeResult<Self> {
+ let mut data = orig_data;
+ let mut v: $working_type = 0;
+ let mut bit_place: usize = 0;
+ let mut i: usize = 0;
+ let mut has_more = true;
+
+ while has_more {
+ if i == $max_bytes {
+ return DeserializeErr::VarNumTooLong(Vec::from(&orig_data[..i])).into();
+ }
+ let Deserialized { value: byte, data: rest } = ProtoByteOrder::read_ubyte(data)?;
+ data = rest;
+ has_more = byte & 0x80 != 0;
+ v |= ((byte as $working_type) & 0x7F) << bit_place;
+ bit_place += 7;
+ i += 1;
+ }
+
+ Deserialized::ok(Self(v as $data_type), data)
+ }
+ }
-impl Serialize for VarLong {
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- let mut data = [0u8; VAR_LONG_BYTES];
- to.serialize_bytes(serialize_var_num(self.0 as u64, &mut data))
- }
-}
+ impl From<$data_type> for $nam {
+ fn from(other: $data_type) -> Self {
+ Self(other)
+ }
+ }
-impl Deserialize for VarLong {
- fn mc_deserialize(orig_data: &[u8]) -> DeserializeResult<'_, Self> {
- Ok(deserialize_var_num(orig_data, VAR_LONG_BYTES)?.map(move |v| VarLong(v as i64)))
- }
-}
+ impl From<$nam> for $data_type {
+ fn from(other: $nam) -> Self {
+ other.0
+ }
+ }
-#[cfg(all(test, feature = "std"))]
-impl TestRandom for VarLong {
- fn test_gen_random() -> Self {
- let out: i64 = rand::random();
- Self(out)
- }
-}
+ impl core::ops::Deref for $nam {
+ type Target = $data_type;
-fn serialize_var_num(data: u64, out: &mut [u8]) -> &[u8] {
- let mut v: u64 = data;
- let mut byte_idx = 0;
- let mut has_more = true;
- while has_more {
- if byte_idx == out.len() {
- panic!("tried to write too much data for Var num");
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
}
- let mut v_byte = (v & 0x7F) as u8;
- v >>= 7;
- has_more = v != 0;
- if has_more {
- v_byte |= 0x80;
+ impl fmt::Display for $nam {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.0)
+ }
}
- out[byte_idx] = v_byte;
- byte_idx += 1;
- }
-
- &out[..byte_idx]
-}
-
-fn deserialize_var_num(orig_data: &[u8], max_bytes: usize) -> DeserializeResult<u64> {
- let mut data = orig_data;
- let mut v: u64 = 0;
- let mut bit_place: usize = 0;
- let mut i: usize = 0;
- let mut has_more = true;
+ impl fmt::Debug for $nam {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(stringify!($nam))?;
+ f.write_str("(")?;
+ write!(f, "{}", self.0)?;
+ f.write_str(")")?;
+ Ok(())
+ }
+ }
- while has_more {
- if i == max_bytes {
- return DeserializeErr::VarNumTooLong(Vec::from(&orig_data[..i])).into();
+ #[cfg(all(test, feature = "std"))]
+ impl TestRandom for $nam {
+ fn test_gen_random() -> Self {
+ let out: $data_type = rand::random();
+ Self(out)
+ }
}
- let Deserialized { value: byte, data: rest} = ProtoByteOrder::read_ubyte(data)?;
- data = rest;
- has_more = byte & 0x80 != 0;
- v |= ((byte as u64) & 0x7F) << bit_place;
- bit_place += 7;
- i += 1;
}
-
- Deserialized::ok(v, data)
}
+def_varnum!(VarInt, i32, u32, 5);
+def_varnum!(VarLong, i64, u64, 10);
+
// STRING
impl Serialize for String {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
@@ -603,8 +450,8 @@ impl BytesSerializer {
}
impl<T> Serialize for Option<T>
-where
- T: Serialize,
+ where
+ T: Serialize,
{
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
match self {
@@ -618,8 +465,8 @@ where
}
impl<T> Deserialize for Option<T>
-where
- T: Deserialize,
+ where
+ T: Deserialize,
{
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
bool::mc_deserialize(data)?.and_then(move |is_present, data| {
@@ -634,8 +481,8 @@ where
#[cfg(all(test, feature = "std"))]
impl<T> TestRandom for Option<T>
-where
- T: TestRandom,
+ where
+ T: TestRandom,
{
fn test_gen_random() -> Self {
let is_present: bool = rand::random();
@@ -649,13 +496,13 @@ where
// SLOT
#[derive(Debug, PartialEq, Clone)]
-pub struct Slot {
+pub struct ItemStack {
pub item_id: VarInt,
pub item_count: i8,
pub nbt: Option<nbt::NamedTag>,
}
-impl Serialize for Slot {
+impl Serialize for ItemStack {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_other(&self.item_id)?;
to.serialize_other(&self.item_count)?;
@@ -666,10 +513,10 @@ impl Serialize for Slot {
}
}
-impl Deserialize for Slot {
+impl Deserialize for ItemStack {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- let Deserialized { value: item_id, data} = VarInt::mc_deserialize(data)?;
- let Deserialized { value: item_count, data} = i8::mc_deserialize(data)?;
+ let Deserialized { value: item_id, data } = VarInt::mc_deserialize(data)?;
+ let Deserialized { value: item_count, data } = i8::mc_deserialize(data)?;
if data.is_empty() {
return Err(DeserializeErr::Eof);
}
@@ -682,8 +529,7 @@ impl Deserialize for Slot {
data: rest,
},
_ => nbt::read_named_tag(data)?.map(move |tag| Some(tag)),
- }
- .map(move |nbt| Slot {
+ }.map(move |nbt| Self {
item_id,
item_count,
nbt,
@@ -692,7 +538,7 @@ impl Deserialize for Slot {
}
#[cfg(all(test, feature = "std"))]
-impl TestRandom for Slot {
+impl TestRandom for ItemStack {
fn test_gen_random() -> Self {
let item_id = VarInt::test_gen_random();
let item_count = i8::test_gen_random() % 65;
@@ -706,6 +552,292 @@ impl TestRandom for Slot {
}
}
+pub type Slot = Option<ItemStack>;
+
+macro_rules! def_vector_type {
+ ($name: ident, $($fnam: ident),+) => {
+ crate::as_item! {
+ pub struct $name<T> {
+ $(pub $fnam: T),+
+ }
+ }
+
+ impl<T> Serialize for $name<T> where T: Serialize {
+ fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
+ $(
+ to.serialize_other(&self.$fnam)?;
+ )+
+ Ok(())
+ }
+ }
+
+ impl<T> Deserialize for $name<T> where T: Deserialize {
+ fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
+ $(let Deserialized { value: $fnam, data } = T::mc_deserialize(data)?;)+
+ Deserialized::ok(Self { $($fnam),+ }, data)
+ }
+ }
+
+ #[cfg(all(test, feature = "std"))]
+ impl<T> TestRandom for $name<T> where T: TestRandom {
+ fn test_gen_random() -> Self {
+ Self {
+ $($fnam: T::test_gen_random(),)+
+ }
+ }
+ }
+
+ impl<T> Clone for $name<T> where T: Clone {
+ fn clone(&self) -> Self {
+ Self {
+ $($fnam: self.$fnam.clone(),)+
+ }
+ }
+ }
+
+ impl<T> Copy for $name<T> where T: Copy {}
+
+ impl<T, Rhs> PartialEq<$name<Rhs>> for $name<T> where T: PartialEq<Rhs> {
+ fn eq(&self, other: &$name<Rhs>) -> bool {
+ $(self.$fnam.eq(&other.$fnam)) && +
+ }
+
+ fn ne(&self, other: &$name<Rhs>) -> bool {
+ $(self.$fnam.ne(&other.$fnam)) || +
+ }
+ }
+
+ impl<T> core::hash::Hash for $name<T> where T: core::hash::Hash {
+ fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
+ $(self.$fnam.hash(state);)+
+ }
+ }
+
+ impl<T> fmt::Debug for $name<T> where T: fmt::Debug {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(stringify!($name))?;
+ f.write_str("( ")?;
+ $(
+ f.write_str(stringify!($fnam))?;
+ f.write_str("=")?;
+ self.$fnam.fmt(f)?;
+ f.write_str(" ")?;
+ )+
+ f.write_str(")")?;
+ Ok(())
+ }
+ }
+
+ impl<T> fmt::Display for $name<T> where T: fmt::Display {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(stringify!($name))?;
+ f.write_str("( ")?;
+ $(
+ f.write_str(stringify!($fnam))?;
+ f.write_str("=")?;
+ self.$fnam.fmt(f)?;
+ f.write_str(" ")?;
+ )+
+ f.write_str(")")?;
+ Ok(())
+ }
+ }
+
+ impl<T> From<$name<T>> for ($(crate::instead_of_ident!($fnam, T)),+) {
+ fn from(other: $name<T>) -> Self {
+ ($(other.$fnam),+)
+ }
+ }
+
+ impl<'a, T> From<&'a $name<T>> for ($(&'a crate::instead_of_ident!($fnam, T)),+) {
+ fn from(other: &'a $name<T>) -> Self {
+ ($(&other.$fnam),+)
+ }
+ }
+
+ impl<'a, T> From<&'a $name<T>> for ($(crate::instead_of_ident!($fnam, T)),+) where T: Clone {
+ fn from(other: &'a $name<T>) -> Self {
+ ($(other.$fnam.clone()),+)
+ }
+ }
+
+ impl<T> From<($(crate::instead_of_ident!($fnam, T)),+)> for $name<T> {
+ fn from(other: ($(crate::instead_of_ident!($fnam, T)),+)) -> Self {
+ let ($($fnam),+) = other;
+ Self { $($fnam),+ }
+ }
+ }
+
+ impl<'a, T> From<&'a ($(crate::instead_of_ident!($fnam, T)),+)> for $name<T> where T: Clone {
+ fn from(other: &'a ($(crate::instead_of_ident!($fnam, T)),+)) -> Self {
+ let ($($fnam),+) = other;
+ $(let $fnam = $fnam.clone();)+
+ Self { $($fnam),+ }
+ }
+ }
+
+ impl<'a, T> From<($(&'a crate::instead_of_ident!($fnam, T)),+)> for $name<T> where T: Clone {
+ fn from(other: ($(&'a crate::instead_of_ident!($fnam, T)),+)) -> Self {
+ let ($($fnam),+) = other;
+ $(let $fnam = $fnam.clone();)+
+ Self { $($fnam),+ }
+ }
+ }
+
+ impl<T> $name<T> {
+ pub fn from_other<O>(other: O) -> Self where O: Into<($(crate::instead_of_ident!($fnam, T)),+)> {
+ let ($($fnam),+) = other.into();
+ Self { $($fnam,)+ }
+ }
+
+ pub fn as_other<O>(&self) -> O where O: From<($(crate::instead_of_ident!($fnam, T)),+)>, T: Clone {
+ O::from(self.into())
+ }
+
+ pub fn into_other<O>(self) -> O where O: From<($(crate::instead_of_ident!($fnam, T)),+)> {
+ O::from(self.into())
+ }
+ }
+ };
+}
+
+def_vector_type!(Vec3, x, y, z);
+def_vector_type!(Vec2, x, y);
+def_vector_type!(ChunkPosition, x, z);
+pub type TopDownPosition<T> = ChunkPosition<T>;
+def_vector_type!(EntityRotation, yaw, pitch);
+
+proto_struct!(EntityLocation<P, R> {
+ position: Vec3<P>,
+ rotation: EntityRotation<R>
+});
+
+#[derive(Clone, Debug, PartialEq)]
+pub struct CountedArray<E, C> {
+ data: Vec<E>,
+ _counter_type: core::marker::PhantomData<C>,
+}
+
+pub trait ArrayCounter: Serialize + Deserialize {
+
+ fn as_count(&self) -> usize;
+
+ fn from_count(count: usize) -> Self;
+}
+
+impl<E, C> Serialize for CountedArray<E, C> where E: Serialize, C: ArrayCounter {
+ fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
+ let count = C::from_count(self.data.len());
+ to.serialize_other(&count)?;
+ for elem in &self.data {
+ to.serialize_other(elem)?;
+ }
+ Ok(())
+ }
+}
+
+impl<E, C> Deserialize for CountedArray<E, C> where E: Deserialize, C: ArrayCounter {
+ fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
+ let Deserialized { value: count, mut data } = C::mc_deserialize(data)?;
+ let count = count.as_count();
+ let mut elems = Vec::with_capacity(count);
+ for _ in 0..count {
+ let Deserialized { value: elem, data: rest } = E::mc_deserialize(data)?;
+ data = rest;
+ elems.push(elem);
+ }
+
+ Deserialized::ok(Self {
+ data: elems,
+ _counter_type: core::marker::PhantomData,
+ }, data)
+ }
+}
+
+impl<E, C> core::ops::Deref for CountedArray<E, C> where C: ArrayCounter {
+ type Target = Vec<E>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.data
+ }
+}
+
+impl<E, C> core::ops::DerefMut for CountedArray<E, C> where C: ArrayCounter {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.data
+ }
+}
+
+impl<E, C> From<CountedArray<E, C>> for Vec<E> where C: ArrayCounter {
+ fn from(other: CountedArray<E, C>) -> Self {
+ other.data
+ }
+}
+
+impl<E, C> From<Vec<E>> for CountedArray<E, C> where C: ArrayCounter {
+ fn from(data: Vec<E>) -> Self {
+ Self {
+ data,
+ _counter_type: core::marker::PhantomData,
+ }
+ }
+}
+
+#[cfg(all(test, feature = "std"))]
+impl<E, C> TestRandom for CountedArray<E, C>
+ where E: TestRandom, C: ArrayCounter
+{
+ fn test_gen_random() -> Self {
+ let elem_count: usize = rand::random::<usize>() % 32;
+ let mut out = Vec::with_capacity(elem_count);
+ for _ in 0..elem_count {
+ out.push(E::test_gen_random());
+ }
+
+ out.into()
+ }
+}
+
+impl ArrayCounter for VarInt {
+ fn as_count(&self) -> usize {
+ self.0 as usize
+ }
+
+ fn from_count(count: usize) -> Self {
+ Self(count as i32)
+ }
+}
+
+impl ArrayCounter for i16 {
+ fn as_count(&self) -> usize {
+ (*self) as usize
+ }
+
+ fn from_count(count: usize) -> Self {
+ count as i16
+ }
+}
+
+impl ArrayCounter for i32 {
+ fn as_count(&self) -> usize {
+ (*self) as usize
+ }
+
+ fn from_count(count: usize) -> Self {
+ count as i32
+ }
+}
+
+impl ArrayCounter for i8 {
+ fn as_count(&self) -> usize {
+ (*self) as usize
+ }
+
+ fn from_count(count: usize) -> Self {
+ count as i8
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -815,7 +947,7 @@ mod tests {
root: nbt::Tag::Compound(alloc::vec![
nbt::Tag::String("test 123".to_owned()).with_name("abc 123")
])
- .with_name("root"),
+ .with_name("root"),
})
}
diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs
index 150fbe6..81079de 100644
--- a/src/v1_15_2.rs
+++ b/src/v1_15_2.rs
@@ -70,8 +70,8 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
LoginEncryptionRequest, 0x01, Login, ClientBound => LoginEncryptionRequestSpec {
server_id: String,
- public_key: VarIntCountedArray<u8>,
- verify_token: VarIntCountedArray<u8>
+ public_key: CountedArray<u8, VarInt>,
+ verify_token: CountedArray<u8, VarInt>
},
LoginSuccess, 0x02, Login, ClientBound => LoginSuccessSpec {
uuid_string: String,
@@ -89,8 +89,8 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
name: String
},
LoginEncryptionResponse, 0x01, Login, ServerBound => LoginEncryptionResponseSpec {
- shared_secret: VarIntCountedArray<u8>,
- verify_token: VarIntCountedArray<u8>
+ shared_secret: CountedArray<u8, VarInt>,
+ verify_token: CountedArray<u8, VarInt>
},
LoginPluginResponse, 0x02, Login, ServerBound => LoginPluginResponseSpec {
message_id: VarInt,
@@ -104,43 +104,29 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
entity_id: VarInt,
object_uuid: UUID4,
entity_type: VarInt,
- x: f64,
- y: f64,
- z: f64,
+ position: Vec3<f64>,
pitch: Angle,
yaw: Angle,
data: i32,
- velocity_x: i16,
- velocity_y: i16,
- velocity_z: i16
+ velocity: Vec3<i16>
},
PlaySpawnExperienceOrb, 0x01, Play, ClientBound => PlaySpawnExperienceOrbSpec {
entity_id: VarInt,
- x: f64,
- y: f64,
- z: f64,
+ position: Vec3<f64>,
count: i16
},
PlaySpawnWeatherEntity, 0x02, Play, ClientBound => PlaySpawnWeatherEntitySpec {
entity_id: VarInt,
entity_type: u8,
- x: f64,
- y: f64,
- z: f64
+ position: Vec3<f64>
},
PlaySpawnLivingEntity, 0x03, Play, ClientBound => PlaySpawnLivingEntitySpec {
entity_id: VarInt,
entity_uuid: UUID4,
entity_type: VarInt,
- x: f64,
- y: f64,
- z: f64,
- yaw: Angle,
- pitch: Angle,
+ location: EntityLocation<f64, Angle>,
head_pitch: Angle,
- velocity_x: i16,
- velocity_y: i16,
- velocity_z: i16
+ velocity: Vec3<i16>
},
PlaySpawnPainting, 0x04, Play, ClientBound => PlaySpawnPaintingSpec {
entity_id: VarInt,
@@ -152,18 +138,14 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
PlaySpawnPlayer, 0x05, Play, ClientBound => PlaySpawnPlayerSpec {
entity_id: VarInt,
uuid: UUID4,
- x: f64,
- y: f64,
- z: f64,
- yaw: Angle,
- pitch: Angle
+ location: EntityLocation<f64, Angle>
},
PlayEntityAnimation, 0x06, Play, ClientBound => PlayEntityAnimationSpec {
entity_id: VarInt,
animation: EntityAnimationKind
},
PlayStatistics, 0x07, Play, ClientBound => PlayStatisticsSpec {
- entries: VarIntCountedArray<Statistic>
+ entries: CountedArray<Statistic, VarInt>
},
PlayAcknowledgePlayerDigging, 0x08, Play, ClientBound => PlayAcknowledgePlayerDiggingSpec {
location: IntPosition,
@@ -204,18 +186,17 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
position: ChatPosition
},
PlayMultiBlockChange, 0x10, Play, ClientBound => PlayMultiBlockChangeSpec {
- chunk_x: i32,
- chunk_z: i32,
- changes: VarIntCountedArray<MultiBlockChangeRecord>
+ chunk: ChunkPosition<i32>,
+ changes: CountedArray<MultiBlockChangeRecord, VarInt>
},
PlayTabComplete, 0x11, Play, ClientBound => PlayTabCompleteSpec {
id: VarInt,
start: VarInt,
length: VarInt,
- matches: VarIntCountedArray<TabCompleteMatch>
+ matches: CountedArray<TabCompleteMatch, VarInt>
},
PlayDeclareCommands, 0x12, Play, ClientBound => PlayDeclareCommandsSpec {
- nodes: VarIntCountedArray<CommandNodeSpec>,
+ nodes: CountedArray<CommandNodeSpec, VarInt>,
root_index: VarInt
},
PlayServerWindowConfirmation, 0x13, Play, ClientBound => PlayServerWindowConfirmationSpec {
@@ -228,7 +209,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayWindowItems, 0x15, Play, ClientBound => PlayWindowItemsSpec {
window_id: u8,
- slots: ShortCountedArray<Option<Slot>>
+ slots: CountedArray<Slot, i16>
},
PlayWindowProperty, 0x16, Play, ClientBound => PlayWindowPropertySpec {
window_id: u8,
@@ -238,7 +219,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
PlaySetSlot, 0x17, Play, ClientBound => PlaySetSlotSpec {
window_id: u8,
slow: i16,
- slot_data: Option<Slot>
+ slot_data: Slot
},
PlaySetCooldown, 0x18, Play, ClientBound => PlaySetCooldownSpec {
item_id: VarInt,
@@ -251,9 +232,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
PlayNamedSoundEffect, 0x1A, Play, ClientBound => PlayNamedSoundEffectSpec {
sound_name: String,
sound_category: SoundCategory,
- position_x: FixedInt,
- position_y: FixedInt,
- position_z: FixedInt,
+ position: Vec3<FixedInt>,
volume: f32,
pitch: f32
},
@@ -265,18 +244,13 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
raw_status: u8 // todo deal with the gigantic table
},
PlayExplosion, 0x1D, Play, ClientBound => PlayExplosionSpec {
- x: f32,
- y: f32,
- z: f32,
+ position: Vec3<f32>,
strength: f32,
- records: IntCountedArray<ExplosionRecord>,
- player_motion_x: f32,
- player_motion_y: f32,
- player_motion_z: f32
+ records: CountedArray<Vec3<i8>, i32>,
+ player_motion: Vec3<f32>
},
PlayUnloadChunk, 0x1E, Play, ClientBound => PlayUnloadChunkSpec {
- x: i32,
- y: i32
+ position: ChunkPosition<i32>
},
PlayChangeGameState, 0x1F, Play, ClientBound => PlayChangeGameStateSpec {
reason: GameChangeReason
@@ -301,18 +275,13 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
PlayParticle, 0x24, Play, ClientBound => PlayParticleSpec {
particle_id: i32,
long_distance: bool,
- x: f64,
- y: f64,
- z: f64,
- offset_x: f32,
- offset_y: f32,
- offset_z: f32,
+ position: Vec3<f64>,
+ offset: Vec3<f32>,
particle_data: i32,
data: RemainingBytes // todo
},
PlayUpdateLight, 0x25, Play, ClientBound => PlayUpdateLightSpec {
- chunk_x: VarInt,
- chunk_z: VarInt,
+ chunk: ChunkPosition<VarInt>,
update: LightingUpdateSpec
},
PlayJoinGame, 0x26, Play, ClientBound => PlayJoinGameSpec {
@@ -331,12 +300,12 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
scale: i8,
tracking_position: bool,
locked: bool,
- icons: VarIntCountedArray<MapIconSpec>,
+ icons: CountedArray<MapIconSpec, VarInt>,
columns: MapColumns
},
PlayTradeList, 0x28, Play, ClientBound => PlayTradeListSpec {
window_id: VarInt,
- trades: ByteCountedArray<TradeSpec>,
+ trades: CountedArray<TradeSpec, i8>,
villager_level: VarInt,
experience: VarInt,
regular_villager: bool,
@@ -344,35 +313,24 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayEntityPosition, 0x29, Play, ClientBound => PlayEntityPositionSpec {
entity_id: VarInt,
- delta_x: i16,
- delta_y: i16,
- delta_z: i16,
+ delta: Vec3<i16>,
on_ground: bool
},
PlayEntityPositionAndRotation, 0x2A, Play, ClientBound => PlayEntityPositionAndRotationSpec {
entity_id: VarInt,
- delta_x: i16,
- delta_y: i16,
- delta_z: i16,
- yaw: Angle,
- pitch: Angle,
+ delta: EntityLocation<i16, Angle>,
on_ground: bool
},
PlayEntityRotation, 0x2B, Play, ClientBound => PlayEntityRotationSpec {
entity_id: VarInt,
- yaw: Angle,
- pitch: Angle,
+ rotation: EntityRotation<Angle>,
on_ground: bool
},
PlayEntityMovement, 0x2C, Play, ClientBound => PlayEntityMovementSpec {
entity_id: VarInt
},
PlayServerVehicleMove, 0x2D, Play, ClientBound => PlayEntityVehicleMoveSpec {
- x: f64,
- y: f64,
- z: f64,
- yaw: f32,
- pitch: f32
+ location: EntityLocation<f64, f32>
},
PlayOpenBook, 0x2E, Play, ClientBound => PlayOpenBookSpec {
hand: Hand
@@ -402,17 +360,11 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayFacePlayer, 0x35, Play, ClientBound => PlayFacePlayerSpec {
face_kind: FacePlayerKind,
- target_x: f64,
- target_y: f64,
- target_z: f64,
+ target: Vec3<f64>,
entity: Option<FacePlayerEntityTarget>
},
PlayServerPlayerPositionAndLook, 0x36, Play, ClientBound => PlayServerPlayerPositionAndLookSpec {
- x: f64,
- y: f64,
- z: f64,
- yaw: f32,
- pitch: f32,
+ location: EntityLocation<f64, f32>,
flags: PositionAndLookFlags,
teleport_id: VarInt
},
@@ -422,11 +374,11 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
crafting_book_active: bool,
smelting_book_open: bool,
smelting_book_active: bool,
- recipe_ids: VarIntCountedArray<String>,
+ recipe_ids: CountedArray<String, VarInt>,
other_recipe_ids: RemainingBytes // todo
},
PlayDestroyEntities, 0x38, Play, ClientBound => PlayDestroyEntitiesSpec {
- entity_ids: VarIntCountedArray<VarInt>
+ entity_ids: CountedArray<VarInt, VarInt>
},
PlayRemoveEntityEffect, 0x39, Play, ClientBound => PlayRemoveEntityEffectSpec {
entity_id: VarInt,
@@ -459,8 +411,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
slot: i8
},
PlayUpdateViewPosition, 0x41, Play, ClientBound => PlayUpdateViewPositionSpec {
- chunk_x: VarInt,
- chunk_z: VarInt
+ chunk: ChunkPosition<VarInt>
},
PlayUpdateViewDistance, 0x42, Play, ClientBound => PlayUpdateViewDistanceSpec {
view_distance: VarInt
@@ -479,14 +430,12 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayEntityVelocity, 0x46, Play, ClientBound => PlayEntityVelocitySpec {
entity_id: VarInt,
- velocity_x: i16,
- velocity_y: i16,
- velocity_z: i16
+ velocity: Vec3<i16>
},
PlayEntityEquipment, 0x47, Play, ClientBound => PlayEntityEquiptmentSpec {
entity_id: VarInt,
slot: EquipmentSlot,
- item: Option<Slot>
+ item: Slot
},
PlaySetExperience, 0x48, Play, ClientBound => PlaySetExperienceSpec {
experience_bar: f32,
@@ -504,7 +453,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlaySetPassengers, 0x4B, Play, ClientBound => PlaySetPassengersSpec {
entity_id: VarInt,
- passenger_entitiy_ids: VarIntCountedArray<VarInt>
+ passenger_entitiy_ids: CountedArray<VarInt, VarInt>
},
PlayTeams, 0x4C, Play, ClientBound => PlayTeamsSpec {
team_name: String,
@@ -534,9 +483,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
PlaySoundEffect, 0x52, Play, ClientBound => PlaySoundEffectSpec {
sound_id: VarInt,
sound_category: SoundCategory,
- position_x: FixedInt,
- position_y: FixedInt,
- position_z: FixedInt,
+ position: Vec3<FixedInt>,
volume: f32,
pitch: f32
},
@@ -558,22 +505,18 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayEntityTeleport, 0x57, Play, ClientBound => PlayEntityTeleportSpec {
entity_id: VarInt,
- x: f64,
- y: f64,
- z: f64,
- yaw: Angle,
- pitch: Angle,
+ location: EntityLocation<f64, Angle>,
on_ground: bool
},
PlayAdvancements, 0x58, Play, ClientBound => PlayAdvancementsSpec {
reset: bool,
- mappings: VarIntCountedArray<AdvancementMappingEntrySpec>,
- identifiers: VarIntCountedArray<String>,
- progress: VarIntCountedArray<AdvancementProgressEntrySpec>
+ mappings: CountedArray<AdvancementMappingEntrySpec, VarInt>,
+ identifiers: CountedArray<String, VarInt>,
+ progress: CountedArray<AdvancementProgressEntrySpec, VarInt>
},
PlayEntityProperties, 0x59, Play, ClientBound => PlayEntityPropertiesSpec {
entity_id: VarInt,
- properties: IntCountedArray<EntityPropertySpec>
+ properties: CountedArray<EntityPropertySpec, i32>
},
PlayEntityEffect, 0x5A, Play, ClientBound => PlayEntityEffectSpec {
entity_id: VarInt,
@@ -583,13 +526,13 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
flags: EntityEffectFlags
},
PlayDeclareRecipes, 0x5B, Play, ClientBound => PlayDeclareRecipesSpec {
- recipes: VarIntCountedArray<RecipeSpec>
+ recipes: CountedArray<RecipeSpec, VarInt>
},
PlayTags, 0x5C, Play, ClientBound => PlayTagsSpec {
- block_tags: VarIntCountedArray<TagSpec>,
- item_tags: VarIntCountedArray<TagSpec>,
- fluid_tags: VarIntCountedArray<TagSpec>,
- entity_tags: VarIntCountedArray<TagSpec>
+ block_tags: CountedArray<TagSpec, VarInt>,
+ item_tags: CountedArray<TagSpec, VarInt>,
+ fluid_tags: CountedArray<TagSpec, VarInt>,
+ entity_tags: CountedArray<TagSpec, VarInt>
},
// play server bound
@@ -640,7 +583,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
button: i8,
action_number: i16,
mode: InventoryOperationMode,
- clicked_item: Option<Slot>
+ clicked_item: Slot
},
PlayClientCloseWindow, 0x0A, Play, ServerBound => PlayClientCloseWindowSpec {
window_id: u8
@@ -650,7 +593,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
data: RemainingBytes
},
PlayEditBook, 0x0C, Play, ServerBound => PlayEditBookSpec {
- new_book: Option<Slot>,
+ new_book: Slot,
is_signing: bool,
hand: Hand
},
@@ -665,33 +608,22 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
locked: bool
},
PlayPlayerPosition, 0x11, Play, ServerBound => PlayPlayerPositionSpec {
- x: f64,
- feet_y: f64,
- z: f64,
+ feet_position: Vec3<f64>,
on_ground: bool
},
PlayClientPlayerPositionAndRotation, 0x12, Play, ServerBound => PlayClientPlayerPositionAndRotationSpec {
- x: f64,
- feet_y: f64,
- z: f64,
- yaw: f32,
- pitch: f32,
+ feet_location: EntityLocation<f64, f32>,
on_ground: bool
},
PlayPlayerRotation, 0x13, Play, ServerBound => PlayPlayerRotationSpec {
- yaw: f32,
- pitch: f32,
+ rotation: EntityRotation<f32>,
on_ground: bool
},
PlayPlayerMovement, 0x14, Play, ServerBound => PlayPlayerMovementSpec {
on_ground: bool
},
PlayClientVehicleMove, 0x15, Play, ServerBound => PlayClientVehicleMoveSpec {
- x: f64,
- y: f64,
- z: f64,
- yaw: f32,
- pitch: f32
+ location: EntityLocation<f64, f32>
},
PlaySteerBoat, 0x16, Play, ServerBound => PlaySteerBoatSpec {
left_paddle_turning: bool,
@@ -760,7 +692,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
},
PlayCreativeInventoryAction, 0x26, Play, ServerBound => PlayCreativeInventoryActionSpec {
slot: i16,
- clicked_item: Option<Slot>
+ clicked_item: Slot
},
PlayUpdateJigsawBlock, 0x27, Play, ServerBound => PlayUpdateJigsawBlockSpec {
location: IntPosition,
@@ -773,12 +705,8 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
action: UpdateStructureBlockAction,
mode: UpdateStructureBlockMode,
name: String,
- offset_x: i8,
- offset_y: i8,
- offset_z: i8,
- size_x: i8,
- size_y: i8,
- size_z: i8,
+ offset: Vec3<i8>,
+ size: Vec3<i8>,
mirror: UpdateStructureBlockMirror,
rotation: UpdateStructureBlockRotation,
metadata: String,
@@ -803,9 +731,7 @@ define_protocol!(Packet578, RawPacket578, RawPacket578Body, PacketDirection, Sta
hand: Hand,
location: IntPosition,
face: DiggingFace,
- cursor_position_x: f32,
- cursor_position_y: f32,
- cursor_position_z: f32,
+ cursor_position: Vec3<f32>,
inside_block: bool
},
PlayUseItem, 0x2D, Play, ServerBound => PlayUseItemSpec {
@@ -821,47 +747,6 @@ proto_byte_enum!(HandshakeNextState,
0x02 :: Login
);
-fn varint_to_usize(v: VarInt) -> usize {
- v.into()
-}
-
-fn varint_from_usize(u: usize) -> VarInt {
- u.into()
-}
-counted_array_type!(
- VarIntCountedArray,
- VarInt,
- varint_to_usize,
- varint_from_usize
-);
-
-fn i16_to_usize(v: i16) -> usize {
- v as usize
-}
-
-fn i16_from_usize(u: usize) -> i16 {
- u as i16
-}
-counted_array_type!(ShortCountedArray, i16, i16_to_usize, i16_from_usize);
-
-fn i32_to_usize(v: i32) -> usize {
- v as usize
-}
-
-fn i32_from_usize(u: usize) -> i32 {
- u as i32
-}
-counted_array_type!(IntCountedArray, i32, i32_to_usize, i32_from_usize);
-
-fn i8_to_usize(v: i8) -> usize {
- v as usize
-}
-
-fn i8_from_usize(u: usize) -> i8 {
- u as i8
-}
-counted_array_type!(ByteCountedArray, i8, i8_to_usize, i8_from_usize);
-
#[derive(Debug, Clone, PartialEq)]
pub struct RemainingBytes {
pub data: Vec<u8>,
@@ -990,7 +875,7 @@ proto_varint_enum!(StatisticKind,
0x31 :: OpenShulkerBox
);
-__protocol_body_def_helper!(Statistic {
+proto_struct!(Statistic {
kind: StatisticCategory,
value: VarInt
});
@@ -1063,7 +948,7 @@ impl TestRandom for BlockChangeHorizontalPosition {
}
}
-__protocol_body_def_helper!(MultiBlockChangeRecord {
+proto_struct!(MultiBlockChangeRecord {
horizontal_position: BlockChangeHorizontalPosition,
y_coordinate: u8,
block_id: VarInt
@@ -1097,12 +982,12 @@ proto_varint_enum!(BossBarDivision,
);
proto_byte_flag!(BossBarFlags,
- 0x01 :: darken_sky,
- 0x02 :: dragon_bar,
- 0x04 :: create_fog
+ 0x01 :: is_darken_sky set_darken_sky,
+ 0x02 :: is_dragon_bar set_dragon_bar,
+ 0x04 :: is_create_fog set_create_fog
);
-__protocol_body_def_helper!(BossBarAddSpec {
+proto_struct!(BossBarAddSpec {
title: Chat,
health: f32,
color: BossBarColor,
@@ -1110,27 +995,27 @@ __protocol_body_def_helper!(BossBarAddSpec {
flags: BossBarFlags
});
-__protocol_body_def_helper!(BossBarUpdateHealthSpec { health: f32 });
+proto_struct!(BossBarUpdateHealthSpec { health: f32 });
-__protocol_body_def_helper!(BossBarUpdateTitleSpec { title: String });
+proto_struct!(BossBarUpdateTitleSpec { title: String });
-__protocol_body_def_helper!(BossBarUpdateStyleSpec {
+proto_struct!(BossBarUpdateStyleSpec {
color: BossBarColor,
dividers: BossBarDivision
});
-__protocol_body_def_helper!(BossBarUpdateFlagsSpec {
+proto_struct!(BossBarUpdateFlagsSpec {
flags: BossBarFlags
});
-__protocol_body_def_helper!(TabCompleteMatch {
+proto_struct!(TabCompleteMatch {
match_: String,
tooltip: Option<Chat>
});
#[derive(Clone, Debug, PartialEq)]
pub struct CommandNodeSpec {
- pub children_indices: VarIntCountedArray<VarInt>,
+ pub children_indices: CountedArray<VarInt, VarInt>,
pub redirect_node: Option<VarInt>,
pub is_executable: bool,
pub node: CommandNode,
@@ -1186,7 +1071,7 @@ impl Serialize for CommandNodeSpec {
impl Deserialize for CommandNodeSpec {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
let Deserialized { value: flags, data } = u8::mc_deserialize(data)?;
- let Deserialized { value: children_indices, data } = <VarIntCountedArray<VarInt>>::mc_deserialize(data)?;
+ let Deserialized { value: children_indices, data } = <CountedArray<VarInt, VarInt>>::mc_deserialize(data)?;
let (redirect_node, data) = if flags & 0x08 != 0 {
let Deserialized { value: redirect_node, data } = VarInt::mc_deserialize(data)?;
(Some(redirect_node), data)
@@ -1215,7 +1100,7 @@ impl Deserialize for CommandNodeSpec {
#[cfg(all(test, feature = "std"))]
impl TestRandom for CommandNodeSpec {
fn test_gen_random() -> Self {
- let children_indices = <VarIntCountedArray<VarInt>>::test_gen_random();
+ let children_indices = <CountedArray<VarInt, VarInt>>::test_gen_random();
let redirect_node = <Option<VarInt>>::test_gen_random();
let is_executable = rand::random::<bool>();
let idx = rand::random::<usize>() % 3;
@@ -1293,7 +1178,7 @@ proto_str_enum!(SuggestionsTypeSpec,
"minecraft:summonable_entities" :: SummonableEntities
);
-__protocol_body_def_helper!(CommandLiteralNodeSpec {
+proto_struct!(CommandLiteralNodeSpec {
name: String
});
@@ -1468,15 +1353,15 @@ proto_varint_enum!(StringParserMode,
);
proto_byte_flag!(EntityParserFlags,
- 0x01 :: single_target,
- 0x02 :: players_only
+ 0x01 :: is_single_target set_single_target,
+ 0x02 :: is_players_only set_players_only
);
proto_byte_flag!(ScoreHolderFlags,
- 0x01 :: multiple
+ 0x01 :: is_multiple set_multiple
);
-__protocol_body_def_helper!(RangeParserProps {
+proto_struct!(RangeParserProps {
decimal: bool
});
@@ -1546,11 +1431,11 @@ proto_str_enum!(TeamCollisionRule,
"never" :: Never
);
-__protocol_body_def_helper!(TeamActionPlayerList {
- entities: VarIntCountedArray<TeamMember>
+proto_struct!(TeamActionPlayerList {
+ entities: CountedArray<TeamMember, VarInt>
});
-__protocol_body_def_helper!(TeamActionCreateSpec {
+proto_struct!(TeamActionCreateSpec {
display_name: Chat,
friendly_flags: TeamFriendlyFlags,
tag_name_visibility: TeamTagNameVisibility,
@@ -1558,10 +1443,10 @@ __protocol_body_def_helper!(TeamActionCreateSpec {
color: VarInt,
prefix: Chat,
suffix: Chat,
- entities: VarIntCountedArray<TeamMember>
+ entities: CountedArray<TeamMember, VarInt>
});
-__protocol_body_def_helper!(TeamActionUpdateInfoSpec {
+proto_struct!(TeamActionUpdateInfoSpec {
display_name: Chat,
friendly_flags: TeamFriendlyFlags,
tag_name_visibility: TeamTagNameVisibility,
@@ -1572,8 +1457,8 @@ __protocol_body_def_helper!(TeamActionUpdateInfoSpec {
});
proto_byte_flag!(TeamFriendlyFlags,
- 0x01 :: allow_friendly_fire,
- 0x02 :: show_invisible_teammates
+ 0x01 :: allow_friendly_fire set_friendly_fire,
+ 0x02 :: show_invisible_teammates set_show_invisible_teammates
);
proto_byte_enum!(UpdateScoreAction,
@@ -1630,7 +1515,7 @@ proto_varint_enum!(TitleActionSpec,
0x05 :: Reset
);
-__protocol_body_def_helper!(TitleTimesSpec {
+proto_struct!(TitleTimesSpec {
fade_in: i32,
stay: i32,
fade_out: i32
@@ -1730,12 +1615,6 @@ impl TestRandom for StopSoundSpec {
}
}
-__protocol_body_def_helper!(ExplosionRecord {
- x: i8,
- y: i8,
- z: i8
-});
-
proto_byte_enum!(GameMode,
0x00 :: Survival,
0x01 :: Creative,
@@ -1880,10 +1759,9 @@ proto_varint_enum!(MapIconType,
0x19 :: TreasureMarker
);
-__protocol_body_def_helper!(MapIconSpec {
+proto_struct!(MapIconSpec {
kind: MapIconType,
- x: i8,
- z: i8,
+ position: TopDownPosition<i8>,
direction: i8,
display_name: Option<Chat>
});
@@ -1894,12 +1772,11 @@ pub enum MapColumns {
Updated(MapColumnsSpec),
}
-__protocol_body_def_helper!(MapColumnsSpec {
+proto_struct!(MapColumnsSpec {
columns: u8,
rows: u8,
- x: u8,
- z: u8,
- data: VarIntCountedArray<u8>
+ position: TopDownPosition<u8>,
+ data: CountedArray<u8, VarInt>
});
impl Serialize for MapColumns {
@@ -1937,7 +1814,13 @@ impl From<Option<MapColumnsSpec>> for MapColumns {
fn from(other: Option<MapColumnsSpec>) -> Self {
use MapColumns::*;
match other {
- Some(body) => Updated(body),
+ Some(body) => {
+ if body.columns == 0 {
+ NoUpdates
+ } else {
+ Updated(body)
+ }
+ },
None => NoUpdates,
}
}
@@ -1950,10 +1833,10 @@ impl TestRandom for MapColumns {
}
}
-__protocol_body_def_helper!(TradeSpec {
- input_item_1: Option<Slot>,
- output_item: Option<Slot>,
- input_item_2: Option<Slot>,
+proto_struct!(TradeSpec {
+ input_item_1: Slot,
+ output_item: Slot,
+ input_item_2: Slot,
trade_disabled: bool,
trade_uses: i32,
max_trade_uses: i32,
@@ -1995,10 +1878,10 @@ proto_varint_enum!(WindowType,
);
proto_byte_flag!(PlayerAbilityFlags,
- 0x01 :: invulnerable,
- 0x02 :: flying,
- 0x04 :: allow_flying,
- 0x08 :: instant_break
+ 0x01 :: is_invulnerable set_invulnerable,
+ 0x02 :: is_flying set_flying,
+ 0x04 :: is_flight_allowed set_flight_allowed,
+ 0x08 :: is_instant_break set_instant_break
);
proto_varint_enum!(CombatEvent,
@@ -2007,73 +1890,39 @@ proto_varint_enum!(CombatEvent,
0x02 :: EntityDead(CombatEntityDeadSpec)
);
-__protocol_body_def_helper!(CombatEndSpec {
+proto_struct!(CombatEndSpec {
duration_ticks: VarInt,
entity_id: i32
});
-__protocol_body_def_helper!(CombatEntityDeadSpec {
+proto_struct!(CombatEntityDeadSpec {
player_id: VarInt,
entity_id: i32,
message: Chat
});
-#[derive(Clone, PartialEq, Debug)]
-pub struct PlayerInfoAction<A: Clone + PartialEq + Debug> {
- pub uuid: UUID4,
- pub action: A,
-}
-
-impl<A> Serialize for PlayerInfoAction<A>
- where
- A: Serialize + Clone + PartialEq + Debug,
-{
- fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_other(&self.uuid)?;
- to.serialize_other(&self.action)
- }
-}
-
-impl<A> Deserialize for PlayerInfoAction<A>
- where
- A: Deserialize + Clone + PartialEq + Debug,
-{
- fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- let Deserialized { value: uuid, data } = UUID4::mc_deserialize(data)?;
- Ok(A::mc_deserialize(data)?.map(move |action| Self { uuid, action }))
- }
-}
-
-#[cfg(all(test, feature = "std"))]
-impl<A> TestRandom for PlayerInfoAction<A>
- where
- A: Clone + PartialEq + Debug + TestRandom
-{
- fn test_gen_random() -> Self {
- Self {
- uuid: UUID4::test_gen_random(),
- action: A::test_gen_random(),
- }
- }
-}
+proto_struct!(PlayerInfoAction<A> {
+ uuid: UUID4,
+ action: A
+});
proto_varint_enum!(PlayerInfoActionList,
- 0x00 :: Add(VarIntCountedArray<PlayerInfoAction<PlayerAddActionSpec>>),
- 0x01 :: UpdateGameMode(VarIntCountedArray<PlayerInfoAction<GameMode>>),
- 0x02 :: UpdateLatency(VarIntCountedArray<PlayerInfoAction<VarInt>>),
- 0x03 :: UpdateDisplayName(VarIntCountedArray<PlayerInfoAction<Option<Chat>>>),
- 0x04 :: Remove(VarIntCountedArray<UUID4>)
+ 0x00 :: Add(CountedArray<PlayerInfoAction<PlayerAddActionSpec>, VarInt>),
+ 0x01 :: UpdateGameMode(CountedArray<PlayerInfoAction<GameMode>, VarInt>),
+ 0x02 :: UpdateLatency(CountedArray<PlayerInfoAction<VarInt>, VarInt>),
+ 0x03 :: UpdateDisplayName(CountedArray<PlayerInfoAction<Option<Chat>>, VarInt>),
+ 0x04 :: Remove(CountedArray<UUID4, VarInt>)
);
-__protocol_body_def_helper!(PlayerAddActionSpec {
+proto_struct!(PlayerAddActionSpec {
name: String,
- properties: VarIntCountedArray<PlayerAddProperty>,
+ properties: CountedArray<PlayerAddProperty, VarInt>,
game_mode: GameMode,
ping_ms: VarInt,
display_name: Option<Chat>
});
-__protocol_body_def_helper!(PlayerAddProperty {
+proto_struct!(PlayerAddProperty {
name: String,
value: String,
signature: Option<String>
@@ -2084,17 +1933,17 @@ proto_varint_enum!(FacePlayerKind,
0x01 :: Eyes
);
-__protocol_body_def_helper!(FacePlayerEntityTarget {
+proto_struct!(FacePlayerEntityTarget {
entity_id: VarInt,
kind: FacePlayerKind
});
proto_byte_flag!(PositionAndLookFlags,
- 0x01 :: x,
- 0x02 :: y,
- 0x04 :: z,
- 0x08 :: y_rotation,
- 0x10 :: x_rotation
+ 0x01 :: is_x_rel set_x_rel,
+ 0x02 :: is_y_rel set_y_rel,
+ 0x04 :: is_z_rel set_z_rel,
+ 0x08 :: is_y_rotation_rel set_y_rotation_rel,
+ 0x10 :: is_x_rotation_rel set_x_rotation_rel
);
proto_byte_enum!(EntityEffectKind,
@@ -2135,25 +1984,24 @@ proto_byte_enum!(EntityEffectKind,
proto_varint_enum!(WorldBorderAction,
0x00 :: SetSize(WorldBorderSetSizeSpec),
0x01 :: LerpSize(WorldBorderLerpSizeSpec),
- 0x02 :: SetCenter(WorldBorderSetCenterSpec),
+ 0x02 :: SetCenter(TopDownPosition<f64>),
0x03 :: Initialize(WorldBorderInitiaializeSpec),
0x04 :: SetWarningTime(WorldBorderWarningTimeSpec),
0x05 :: SetWarningBlocks(WorldBorderWarningBlocksSpec)
);
-__protocol_body_def_helper!(WorldBorderSetSizeSpec { diameter: f64 });
+proto_struct!(WorldBorderSetSizeSpec {
+ diameter: f64
+});
-__protocol_body_def_helper!(WorldBorderLerpSizeSpec {
+proto_struct!(WorldBorderLerpSizeSpec {
old_diameter: f64,
new_diameter: f64,
speed: VarLong
});
-__protocol_body_def_helper!(WorldBorderSetCenterSpec { x: f64, z: f64 });
-
-__protocol_body_def_helper!(WorldBorderInitiaializeSpec {
- x: f64,
- z: f64,
+proto_struct!(WorldBorderInitiaializeSpec {
+ position: TopDownPosition<f64>,
old_diameter: f64,
new_diameter: f64,
speed: VarLong,
@@ -2162,11 +2010,11 @@ __protocol_body_def_helper!(WorldBorderInitiaializeSpec {
warning_blocks: VarInt
});
-__protocol_body_def_helper!(WorldBorderWarningTimeSpec {
+proto_struct!(WorldBorderWarningTimeSpec {
warning_time: VarInt
});
-__protocol_body_def_helper!(WorldBorderWarningBlocksSpec {
+proto_struct!(WorldBorderWarningBlocksSpec {
warning_blocks: VarInt
});
@@ -2197,31 +2045,30 @@ proto_varint_enum!(ScoreboardObjectiveKind,
0x01 :: Hearts
);
-__protocol_body_def_helper!(ScoreboardObjectiveSpec {
+proto_struct!(ScoreboardObjectiveSpec {
text: Chat,
kind: ScoreboardObjectiveKind
});
-__protocol_body_def_helper!(AdvancementMappingEntrySpec {
+proto_struct!(AdvancementMappingEntrySpec {
key: String,
value: AdvancementSpec
});
-__protocol_body_def_helper!(AdvancementSpec {
+proto_struct!(AdvancementSpec {
parent: Option<String>,
display: Option<AdvancementDisplaySpec>,
- criteria: VarIntCountedArray<String>,
- requirements: VarIntCountedArray<VarIntCountedArray<String>>
+ criteria: CountedArray<String, VarInt>,
+ requirements: CountedArray<CountedArray<String, VarInt>, VarInt>
});
-__protocol_body_def_helper!(AdvancementDisplaySpec {
+proto_struct!(AdvancementDisplaySpec {
title: Chat,
description: Chat,
- icon: Option<Slot>,
+ icon: Slot,
frame_type: AdvancementFrameType,
flags: AdvancementDisplayFlags,
- x: f32,
- y: f32
+ position: Vec2<f32>
});
#[derive(Clone, Debug, PartialEq)]
@@ -2299,31 +2146,31 @@ proto_varint_enum!(AdvancementFrameType,
0x02 :: Goal
);
-__protocol_body_def_helper!(AdvancementProgressEntrySpec {
+proto_struct!(AdvancementProgressEntrySpec {
key: String,
value: AdvancementProgressSpec
});
-__protocol_body_def_helper!(AdvancementProgressSpec {
- criteria: VarIntCountedArray<AdvancementCriteriaSpec>
+proto_struct!(AdvancementProgressSpec {
+ criteria: CountedArray<AdvancementCriteriaSpec, VarInt>
});
-__protocol_body_def_helper!(AdvancementCriteriaSpec {
+proto_struct!(AdvancementCriteriaSpec {
identifier: String,
progress: AdvancementCriterionProgressSpec
});
-__protocol_body_def_helper!(AdvancementCriterionProgressSpec {
+proto_struct!(AdvancementCriterionProgressSpec {
achieved_at: Option<i64>
});
-__protocol_body_def_helper!(EntityPropertySpec {
+proto_struct!(EntityPropertySpec {
key: String,
value: f64,
- modifiers: VarIntCountedArray<EntityPropertyModifierSpec>
+ modifiers: CountedArray<EntityPropertyModifierSpec, VarInt>
});
-__protocol_body_def_helper!(EntityPropertyModifierSpec {
+proto_struct!(EntityPropertyModifierSpec {
uuid: UUID4,
amount: f64,
operation: EntityPropertyModifierOperation
@@ -2336,14 +2183,14 @@ proto_byte_enum!(EntityPropertyModifierOperation,
);
proto_byte_flag!(EntityEffectFlags,
- 0x01 :: ambient,
- 0x02 :: show_particles,
- 0x04 :: show_icon
+ 0x01 :: is_ambient set_ambient,
+ 0x02 :: is_show_particles set_show_particles,
+ 0x04 :: is_show_icon set_show_icon
);
-__protocol_body_def_helper!(TagSpec {
+proto_struct!(TagSpec {
name: String,
- entries: VarIntCountedArray<VarInt>
+ entries: CountedArray<VarInt, VarInt>
});
proto_varint_enum!(ClientStatusAction,
@@ -2363,13 +2210,13 @@ proto_varint_enum!(ClientMainHand,
);
proto_byte_flag!(ClientDisplayedSkinParts,
- 0x01 :: cape_enabled,
- 0x02 :: jacket_enabled,
- 0x04 :: left_sleeve_enabled,
- 0x08 :: right_sleeve_enabled,
- 0x10 :: left_pants_leg_enabled,
- 0x20 :: right_pant_legs_enabled,
- 0x40 :: hat_enabled
+ 0x01 :: is_cape_enabled set_cape_enabled,
+ 0x02 :: is_jacket_enabled set_jacket_enabled,
+ 0x04 :: is_left_sleeve_enabled set_left_sleeve_enabled,
+ 0x08 :: is_right_sleeve_enabled set_right_sleeve_enabled,
+ 0x10 :: is_left_pants_leg_enabled set_left_pants_leg_enabled,
+ 0x20 :: is_right_pant_legs_enabled set_right_pant_legs_enabled,
+ 0x40 :: is_hat_enabled set_hat_enabled
);
proto_varint_enum!(InventoryOperationMode,
@@ -2382,10 +2229,8 @@ proto_varint_enum!(InventoryOperationMode,
0x06 :: DoubleClick
);
-__protocol_body_def_helper!(InteractAtSpec {
- target_x: f32,
- target_y: f32,
- target_z: f32,
+proto_struct!(InteractAtSpec {
+ target_position: Vec3<f32>,
hand: Hand
});
@@ -2396,10 +2241,10 @@ proto_varint_enum!(InteractKind,
);
proto_byte_flag!(ClientPlayerAbilities,
- 0x01 :: creative,
- 0x02 :: flying,
- 0x04 :: fly_enabled,
- 0x08 :: damaged_disabled
+ 0x01 :: is_creative set_creative,
+ 0x02 :: is_flying set_flying,
+ 0x04 :: is_fly_enabled set_fly_enabled,
+ 0x08 :: is_damaged_disabled set_damaged_disabled
);
proto_varint_enum!(PlayerDiggingStatus,
@@ -2434,8 +2279,8 @@ proto_varint_enum!(EntityActionKind,
);
proto_byte_flag!(SteerVehicleFlags,
- 0x01 :: jump,
- 0x02 :: unmount
+ 0x01 :: is_jump set_jump,
+ 0x02 :: is_unmount set_unmount
);
proto_varint_enum!(RecipeBookStatus,
@@ -2443,7 +2288,7 @@ proto_varint_enum!(RecipeBookStatus,
0x01 :: States(RecipeBookStates)
);
-__protocol_body_def_helper!(RecipeBookStates {
+proto_struct!(RecipeBookStates {
crafting_book_open: bool,
craftinb_filter_active: bool,
smelting_book_open: bool,
@@ -2473,9 +2318,9 @@ proto_varint_enum!(CommandBlockMode,
);
proto_byte_flag!(CommandBlockFlags,
- 0x01 :: track_output,
- 0x02 :: conditional,
- 0x04 :: automatic
+ 0x01 :: is_track_output set_track_output,
+ 0x02 :: is_conditional set_conditional,
+ 0x04 :: is_automatic set_automatic
);
proto_varint_enum!(UpdateStructureBlockAction,
@@ -2506,9 +2351,9 @@ proto_varint_enum!(UpdateStructureBlockRotation,
);
proto_byte_flag!(UpdateStructureBlockFlags,
- 0x01 :: ignore_entities,
- 0x02 :: show_air,
- 0x04 :: show_bounding_box
+ 0x01 :: is_ignore_entities set_ignore_entities,
+ 0x02 :: is_show_air set_show_air,
+ 0x04 :: is_show_bounding_box set_show_bounding_box
);
#[derive(Clone, PartialEq, Debug)]
@@ -2577,14 +2422,14 @@ impl TestRandom for RecipeSpec {
}
}
-__protocol_body_def_helper!(RecipeIngredient {
- items: VarIntCountedArray<Option<Slot>>
+proto_struct!(RecipeIngredient {
+ items: CountedArray<Slot, VarInt>
});
-__protocol_body_def_helper!(RecipeCraftingShapelessSpec {
+proto_struct!(RecipeCraftingShapelessSpec {
group: String,
- ingredients: VarIntCountedArray<RecipeIngredient>,
- result: Option<Slot>
+ ingredients: CountedArray<RecipeIngredient, VarInt>,
+ result: Slot
});
#[derive(Debug, Clone, PartialEq)]
@@ -2593,7 +2438,7 @@ pub struct RecipeCraftingShapedSpec {
pub height: VarInt,
pub group: String,
pub ingredients: Vec<RecipeIngredient>,
- pub result: Option<Slot>,
+ pub result: Slot,
}
impl Serialize for RecipeCraftingShapedSpec {
@@ -2623,7 +2468,7 @@ impl Deserialize for RecipeCraftingShapedSpec {
ingredients.push(elem);
}
- let Deserialized { value: result, data } = <Option<Slot>>::mc_deserialize(data)?;
+ let Deserialized { value: result, data } = Slot::mc_deserialize(data)?;
Deserialized::ok(
Self {
@@ -2658,23 +2503,23 @@ impl TestRandom for RecipeCraftingShapedSpec {
height,
group: String::test_gen_random(),
ingredients,
- result: Some(Slot::test_gen_random()),
+ result: Some(ItemStack::test_gen_random()),
}
}
}
-__protocol_body_def_helper!(RecipeSmeltingSpec {
+proto_struct!(RecipeSmeltingSpec {
group: String,
ingredient: RecipeIngredient,
- result: Option<Slot>,
+ result: Slot,
experience: f32,
cooking_time: VarInt
});
-__protocol_body_def_helper!(RecipeStonecuttingSpec {
+proto_struct!(RecipeStonecuttingSpec {
group: String,
ingredient: RecipeIngredient,
- result: Option<Slot>
+ result: Slot
});
proto_varint_enum!(RecipeUnlockAction,
@@ -2685,19 +2530,17 @@ proto_varint_enum!(RecipeUnlockAction,
#[derive(Clone, PartialEq, Debug)]
pub struct ChunkData {
- pub chunk_x: i32,
- pub chunk_z: i32,
+ pub position: ChunkPosition<i32>,
pub primary_bit_mask: VarInt,
pub heightmaps: NamedNbtTag,
pub biomes: Option<[i32; 1024]>,
- pub data: VarIntCountedArray<u8>,
+ pub data: CountedArray<u8, VarInt>,
pub block_entities: Vec<NamedNbtTag>,
}
impl Serialize for ChunkData {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_other(&self.chunk_x)?;
- to.serialize_other(&self.chunk_z)?;
+ to.serialize_other(&self.position)?;
let full_chunk = self.biomes.is_some();
to.serialize_other(&full_chunk)?;
to.serialize_other(&self.primary_bit_mask)?;
@@ -2723,8 +2566,7 @@ impl Serialize for ChunkData {
impl Deserialize for ChunkData {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
- let Deserialized { value: chunk_x, data } = i32::mc_deserialize(data)?;
- let Deserialized { value: chunk_z, data } = i32::mc_deserialize(data)?;
+ let Deserialized { value: position, data } = <ChunkPosition<i32>>::mc_deserialize(data)?;
let Deserialized { value: is_full_chunk, data } = bool::mc_deserialize(data)?;
let Deserialized { value: primary_bit_mask, data } = VarInt::mc_deserialize(data)?;
let Deserialized { value: heightmaps, mut data } = NamedNbtTag::mc_deserialize(data)?;
@@ -2739,7 +2581,7 @@ impl Deserialize for ChunkData {
} else {
None
};
- let Deserialized { value: chunk_data, data } = VarIntCountedArray::<u8>::mc_deserialize(data)?;
+ let Deserialized { value: chunk_data, data } = <CountedArray<u8, VarInt>>::mc_deserialize(data)?;
let Deserialized { value: n_block_entities_raw, mut data } = VarInt::mc_deserialize(data)?;
let n_block_entities = n_block_entities_raw.0 as usize;
let mut block_entities = Vec::with_capacity(n_block_entities);
@@ -2750,8 +2592,7 @@ impl Deserialize for ChunkData {
}
Deserialized::ok(ChunkData {
- chunk_x,
- chunk_z,
+ position,
primary_bit_mask,
heightmaps,
biomes,
@@ -2765,12 +2606,11 @@ impl Deserialize for ChunkData {
impl TestRandom for ChunkData {
fn test_gen_random() -> Self {
ChunkData {
- chunk_x: rand::random(),
- chunk_z: rand::random(),
+ position: <ChunkPosition<i32>>::test_gen_random(),
primary_bit_mask: VarInt::test_gen_random(),
heightmaps: NamedNbtTag::test_gen_random(),
biomes: None,
- data: <VarIntCountedArray<u8>>::test_gen_random(),
+ data: <CountedArray<u8, VarInt>>::test_gen_random(),
block_entities: vec![],
}
}
@@ -3090,9 +2930,9 @@ proto_varint_enum!(EntityMetadataFieldData,
0x03 :: String(String),
0x04 :: Chat(Chat),
0x05 :: OptChat(Option<Chat>),
- 0x06 :: Slot(Option<Slot>),
+ 0x06 :: Slot(Slot),
0x07 :: Boolean(bool),
- 0x08 :: Rotation(EntityRotation),
+ 0x08 :: Rotation(Vec3<f32>),
0x09 :: Position(IntPosition),
0x0A :: OptPosition(Option<IntPosition>),
0x0B :: Direction(EntityDirection),
@@ -3105,12 +2945,6 @@ proto_varint_enum!(EntityMetadataFieldData,
0x12 :: Pose(EntityPose)
);
-__protocol_body_def_helper!(EntityRotation {
- x: f32,
- y: f32,
- z: f32
-});
-
proto_varint_enum!(EntityDirection,
0x00 :: Down,
0x01 :: Up,
@@ -3120,7 +2954,7 @@ proto_varint_enum!(EntityDirection,
0x05 :: East
);
-__protocol_body_def_helper!(EntityVillagerData {
+proto_struct!(EntityVillagerData {
villager_type: VillagerType,
villager_profession: VillagerProfession,
level: VarInt
@@ -3197,7 +3031,7 @@ proto_varint_enum!(ParticleSpec,
0x1D :: Composter,
0x1E :: Heart,
0x1F :: InstantEffect,
- 0x20 :: Item(Option<Slot>),
+ 0x20 :: Item(Slot),
0x21 :: ItemSlime,
0x22 :: ItemSnowball,
0x23 :: LargeSmoke,
@@ -3229,11 +3063,11 @@ proto_varint_enum!(ParticleSpec,
0x3D :: FallingNectar
);
-__protocol_body_def_helper!(BlockParticleData {
+proto_struct!(BlockParticleData {
block_state: VarInt
});
-__protocol_body_def_helper!(DustParticleData {
+proto_struct!(DustParticleData {
red: f32,
green: f32,
blue: f32,