aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Sacchini <joey@sacchini.net>2020-09-29 17:05:58 -0400
committerJoey Sacchini <joey@sacchini.net>2020-09-29 17:05:58 -0400
commit56181da142f5e95a067feea5c4558fef2a2d49a7 (patch)
tree08d5bbcaaa13cf915248cf9dba2a0955d4b573cf
parent2e6119a65f260f460dd67860dd5f5af7286bcb42 (diff)
downloadmcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.tar.gz
mcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.tar.bz2
mcproto-rs-56181da142f5e95a067feea5c4558fef2a2d49a7.zip
implement automated testing of all data-types
-rw-r--r--src/lib.rs7
-rw-r--r--src/nbt.rs63
-rw-r--r--src/protocol.rs121
-rw-r--r--src/status.rs21
-rw-r--r--src/test_macros.rs80
-rw-r--r--src/types.rs196
-rw-r--r--src/v1_15_2.rs668
7 files changed, 1096 insertions, 60 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b04090f..1d99ee6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,6 +8,7 @@ extern crate test;
mod serialize;
mod deserialize;
pub mod utils;
+#[macro_export]
pub mod protocol;
pub mod uuid;
pub mod nbt;
@@ -16,4 +17,8 @@ pub mod v1_15_2;
pub mod status;
pub use serialize::*;
-pub use deserialize::*; \ No newline at end of file
+pub use deserialize::*;
+
+#[cfg(test)]
+#[macro_export]
+mod test_macros; \ No newline at end of file
diff --git a/src/nbt.rs b/src/nbt.rs
index ac2d39c..f784454 100644
--- a/src/nbt.rs
+++ b/src/nbt.rs
@@ -1,6 +1,7 @@
use std::fmt;
use crate::{DeserializeResult, DeserializeErr, Deserialized};
use crate::utils::{read_short, take, read_int, read_long, read_one_byte, write_long, write_int, write_short};
+use crate::protocol::TestRandom;
#[derive(Clone, Debug, PartialEq)]
pub struct NamedTag {
@@ -21,6 +22,16 @@ impl NamedTag {
}
}
+#[cfg(test)]
+impl TestRandom for NamedTag {
+ fn test_gen_random() -> Self {
+ Self {
+ name: String::test_gen_random(),
+ payload: Tag::test_gen_random(),
+ }
+ }
+}
+
impl fmt::Display for NamedTag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("TAG_{}('{}'): ", self.payload.tag_type_name(), self.name))?;
@@ -104,6 +115,50 @@ impl Tag {
}
}
+#[cfg(test)]
+impl TestRandom for Tag {
+ fn test_gen_random() -> Self {
+ let random_idx = rand::random::<usize>() % 8;
+ match random_idx {
+ 0 => Tag::Byte(i8::test_gen_random()),
+ 1 => Tag::Short(i16::test_gen_random()),
+ 2 => Tag::Int(i32::test_gen_random()),
+ 3 => Tag::Long(i64::test_gen_random()),
+ 4 => Tag::Float(f32::test_gen_random()),
+ 5 => Tag::Double(f64::test_gen_random()),
+ 6 => Tag::String(String::test_gen_random()),
+ 7 => Tag::List({
+ let count = rand::random::<usize>() % 256;
+ let mut out = Vec::with_capacity(count);
+ let random_idx = rand::random::<usize>() % 6;
+ for _ in 0..count {
+ out.push(match random_idx {
+ 0 => Tag::Byte(i8::test_gen_random()),
+ 1 => Tag::Short(i16::test_gen_random()),
+ 2 => Tag::Int(i32::test_gen_random()),
+ 3 => Tag::Long(i64::test_gen_random()),
+ 4 => Tag::Float(f32::test_gen_random()),
+ 5 => Tag::Double(f64::test_gen_random()),
+ 6 => Tag::String(String::test_gen_random()),
+ other => panic!("impossible {}", other)
+ });
+ }
+
+ out
+ }),
+ 8 => Tag::Compound({
+ let count = rand::random::<usize>() % 256;
+ let mut out = Vec::with_capacity(count);
+ for _ in 0..count {
+ out.push(NamedTag::test_gen_random());
+ }
+ out
+ }),
+ other => panic!("impossible {}", other),
+ }
+ }
+}
+
#[inline]
fn write_contents<F>(contents: &Vec<F>) -> String where F: fmt::Display {
format!("{} entries\n{{\n{}\n}}", contents.len(), contents.iter()
@@ -466,7 +521,7 @@ mod tests {
let (unzipped, result) = read_bigtest_with_bytes();
let serialized = result.bytes();
assert_eq!(unzipped, serialized);
- let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(serialized.as_slice()).expect("deserialize serialized nbt");
+ let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(serialized.as_slice()).expect("deserialize serialized nbt");
assert_eq!(unserialized, result);
}
@@ -477,7 +532,7 @@ mod tests {
)).with_name("test");
let bytes = original.bytes();
- let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array");
+ let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array");
assert_eq!(original, unserialized);
}
@@ -488,7 +543,7 @@ mod tests {
)).with_name("test");
let bytes = original.bytes();
- let Deserialized{value: unserialized, data: _} = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array");
+ let Deserialized { value: unserialized, data: _ } = NamedTag::root_compound_tag_from_bytes(bytes.as_slice()).expect("deserialize int array");
assert_eq!(original, unserialized);
}
@@ -504,7 +559,7 @@ mod tests {
fn read_bigtest_with_bytes() -> (Vec<u8>, NamedTag) {
let unzipped = read_compressed_file("src/testdata/bigtest.nbt").expect("read nbt data");
- let Deserialized{value: result, data: rest} = NamedTag::root_compound_tag_from_bytes(unzipped.as_slice()).expect("deserialize nbt");
+ let Deserialized { value: result, data: rest } = NamedTag::root_compound_tag_from_bytes(unzipped.as_slice()).expect("deserialize nbt");
assert_eq!(rest.len(), 0);
(unzipped, result)
diff --git a/src/protocol.rs b/src/protocol.rs
index 01265df..e768fdb 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -13,6 +13,7 @@ pub struct ProtocolPacketSpec {
pub direction: String,
pub id: i32,
pub name: String,
+ pub body_struct: String,
pub fields: Vec<ProtocolPacketField>,
}
@@ -35,7 +36,7 @@ pub trait Packet<I: PacketIdentifier>: Serialize {
#[derive(Debug)]
pub enum PacketErr {
UnknownId(i32),
- DeserializeFailed(DeserializeErr)
+ DeserializeFailed(DeserializeErr),
}
#[derive(Debug, Clone, PartialEq)]
@@ -48,6 +49,11 @@ pub trait ProtocolType: Serialize + Deserialize {}
impl<T: Serialize + Deserialize> ProtocolType for T {}
+#[cfg(test)]
+pub trait TestRandom {
+ fn test_gen_random() -> Self;
+}
+
#[macro_export]
macro_rules! as_item {
($i:item) => { $i };
@@ -82,6 +88,13 @@ macro_rules! __protocol_body_def_helper {
Deserialized::ok(Self::default(), data)
}
}
+
+ #[cfg(test)]
+ impl TestRandom for $bodyt {
+ fn test_gen_random() -> Self {
+ Self::default()
+ }
+ }
};
($bodyt: ident { $($fname: ident: $ftyp: ty ),+ }) => {
$crate::as_item! {
@@ -107,6 +120,13 @@ macro_rules! __protocol_body_def_helper {
Deserialized::ok(Self{ $($fname),+ }, _rest)
}
}
+
+ #[cfg(test)]
+ impl TestRandom for $bodyt {
+ fn test_gen_random() -> Self {
+ Self{ $($fname: <$ftyp>::test_gen_random()),+ }
+ }
+ }
}
}
@@ -189,6 +209,7 @@ macro_rules! define_protocol {
direction: stringify!($direction).to_owned(),
id: $id,
name: stringify!($nam).to_owned(),
+ body_struct: stringify!($body).to_owned(),
fields: vec!(
$(crate::protocol::ProtocolPacketField{
name: stringify!($fnam).to_owned(),
@@ -206,6 +227,13 @@ macro_rules! define_protocol {
}
#[macro_export]
+macro_rules! count_num {
+ () => { 0 };
+ ($item: tt) => { 1 };
+ ($item: tt, $($rest: tt),+) => { 1 + count_num!($($rest),+) }
+}
+
+#[macro_export]
macro_rules! proto_enum_with_type {
($typ: ty, $from_nam: ident, $as_nam: ident, $fmt: literal, $typname: ident, $(($bval: literal, $nam: ident)),*) => {
$crate::as_item! {
@@ -274,6 +302,20 @@ macro_rules! proto_enum_with_type {
(*self).into()
}
}
+
+ #[cfg(test)]
+ impl TestRandom for $typname {
+ fn test_gen_random() -> Self {
+ let mut idx: usize = (rand::random::<usize>() % (count_num!($($bval),+))) + 1;
+ $(
+ idx -= 1;
+ if idx == 0 {
+ return $typname::$nam;
+ }
+ )+
+ panic!("cannot generate random {}", stringify!($typname));
+ }
+ }
}
}
@@ -345,5 +387,80 @@ macro_rules! proto_byte_flag {
Ok(u8::mc_deserialize(data)?.map(move |b| $typname(b)))
}
}
+
+ #[cfg(test)]
+ impl TestRandom for $typname {
+ fn test_gen_random() -> Self {
+ let mut out = <$typname>::default();
+ $(paste::paste! {
+ out.[<set_ $nam>](rand::random::<bool>());
+ })+
+ out
+ }
+ }
}
-} \ No newline at end of file
+}
+
+#[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 }
+ }
+ }
+
+ #[cfg(test)]
+ 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 }
+ }
+ }
+ }
+}
diff --git a/src/status.rs b/src/status.rs
index b8f9029..7d254aa 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -3,6 +3,7 @@ use crate::{SerializeResult, SerializeErr, Serialize as McSerialize, Deserialize
use crate::uuid::UUID4;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use std::fmt;
+use crate::protocol::TestRandom;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatusSpec {
@@ -31,6 +32,26 @@ impl McDeserialize for StatusSpec {
}
}
+
+#[cfg(test)]
+impl TestRandom for StatusSpec {
+ fn test_gen_random() -> Self {
+ Self {
+ version: StatusVersionSpec{
+ protocol: rand::random(),
+ name: String::test_gen_random(),
+ },
+ players: StatusPlayersSpec{
+ sample: Vec::default(),
+ max: rand::random(),
+ online: rand::random(),
+ },
+ favicon: None,
+ description: Chat::test_gen_random(),
+ }
+ }
+}
+
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatusVersionSpec {
pub name: String,
diff --git a/src/test_macros.rs b/src/test_macros.rs
new file mode 100644
index 0000000..cc573a7
--- /dev/null
+++ b/src/test_macros.rs
@@ -0,0 +1,80 @@
+use crate::{Serializer, SerializeResult};
+#[cfg(test)]
+#[macro_export]
+macro_rules! packet_test_cases {
+ ($pnam: ident, $varnam: ident, $bodnam: ident, $testnam: ident, $benchnams: ident, $benchnamd: ident) => {
+ #[test]
+ fn $testnam() {
+ for _ in 0..10 {
+ let packet = $pnam::$varnam($bodnam::test_gen_random());
+ let mut out = BytesSerializer::default();
+ packet.mc_serialize(&mut out).expect("serialize succeeds");
+ let bytes = out.into_bytes();
+
+ let raw_packet = RawPacket{
+ id: packet.id(),
+ data: bytes,
+ };
+
+ let deserialized = <$pnam>::mc_deserialize(raw_packet).expect("deserialize succeeds");
+ assert_eq!(packet, deserialized);
+ }
+ }
+
+ #[bench]
+ fn $benchnams(b: &mut Bencher) {
+ let packet = $pnam::$varnam($bodnam::test_gen_random());
+ let mut serializer = BenchSerializer::default();
+ packet.mc_serialize(&mut serializer).expect("serialize succeeds");
+ b.bytes = serializer.len() as u64;
+ serializer.reset();
+
+ b.iter(|| {
+ packet.mc_serialize(&mut serializer).expect("serialize succeeds");
+ serializer.reset();
+ })
+ }
+
+ #[bench]
+ fn $benchnamd(b: &mut Bencher) {
+ let packet = $pnam::$varnam($bodnam::test_gen_random());
+ let mut serializer = BytesSerializer::default();
+ packet.mc_serialize(&mut serializer).expect("serialize succeeds");
+
+ let bytes = serializer.into_bytes();
+ b.bytes = bytes.len() as u64;
+ let raw_packet = RawPacket{
+ id: packet.id(),
+ data: bytes,
+ };
+ b.iter(|| {
+ $pnam::mc_deserialize(raw_packet.clone()).expect("deserialize succeeds");
+ })
+ }
+ }
+}
+
+#[cfg(test)]
+#[derive(Clone, Debug, Default, PartialEq)]
+pub struct BenchSerializer {
+ data: Vec<u8>
+}
+
+#[cfg(test)]
+impl Serializer for BenchSerializer {
+ fn serialize_bytes(&mut self, data: &[u8]) -> SerializeResult {
+ self.data.extend_from_slice(data);
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+impl BenchSerializer {
+ pub fn reset(&mut self) {
+ self.data.clear();
+ }
+
+ pub fn len(&self) -> usize {
+ self.data.len()
+ }
+} \ No newline at end of file
diff --git a/src/types.rs b/src/types.rs
index f62ede9..9d8f595 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -4,6 +4,9 @@ use crate::*;
use crate::utils::*;
use crate::uuid::UUID4;
+#[cfg(test)]
+use crate::protocol::TestRandom;
+
// bool
impl Serialize for bool {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
@@ -23,6 +26,13 @@ impl Deserialize for bool {
}
}
+#[cfg(test)]
+impl TestRandom for bool {
+ fn test_gen_random() -> Self {
+ rand::random()
+ }
+}
+
// u8
impl Serialize for u8 {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
@@ -36,6 +46,13 @@ impl Deserialize for u8 {
}
}
+#[cfg(test)]
+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 {
@@ -49,6 +66,13 @@ impl Deserialize for i8 {
}
}
+#[cfg(test)]
+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 {
@@ -63,6 +87,13 @@ impl Deserialize for u16 {
}
}
+#[cfg(test)]
+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 {
@@ -76,6 +107,13 @@ impl Deserialize for i16 {
}
}
+#[cfg(test)]
+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 {
@@ -90,6 +128,13 @@ impl Deserialize for i32 {
}
}
+#[cfg(test)]
+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 {
@@ -104,6 +149,13 @@ impl Deserialize for i64 {
}
}
+#[cfg(test)]
+impl TestRandom for i64 {
+ fn test_gen_random() -> Self {
+ rand::random()
+ }
+}
+
// float
impl Serialize for f32 {
@@ -120,6 +172,13 @@ impl Deserialize for f32 {
}
}
+#[cfg(test)]
+impl TestRandom for f32 {
+ fn test_gen_random() -> Self {
+ rand::random()
+ }
+}
+
// double
impl Serialize for f64 {
//noinspection ALL
@@ -135,6 +194,13 @@ impl Deserialize for f64 {
}
}
+#[cfg(test)]
+impl TestRandom for f64 {
+ fn test_gen_random() -> Self {
+ rand::random()
+ }
+}
+
// VAR INT AND VAR LONG
const VAR_INT_BYTES: usize = 5;
const VAR_LONG_BYTES: usize = 10;
@@ -188,6 +254,14 @@ impl std::fmt::Display for VarInt {
}
}
+#[cfg(test)]
+impl TestRandom for VarInt {
+ fn test_gen_random() -> Self {
+ let out: i32 = rand::random();
+ Self(out)
+ }
+}
+
#[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Default, Hash, Ord, Eq)]
pub struct VarLong(pub i64);
@@ -204,6 +278,14 @@ impl Deserialize for VarLong {
}
}
+#[cfg(test)]
+impl TestRandom for VarLong {
+ fn test_gen_random() -> Self {
+ let out: i64 = rand::random();
+ Self(out)
+ }
+}
+
fn serialize_var_num(data: u64, out: &mut [u8]) -> &[u8] {
let mut v: u64 = data;
let mut byte_idx = 0;
@@ -274,6 +356,28 @@ impl Deserialize for String {
}
}
+#[cfg(test)]
+impl TestRandom for String {
+ fn test_gen_random() -> Self {
+ let raw_len: u8 = rand::random();
+ let len = raw_len as usize;
+ let mut out = String::with_capacity(len);
+ for _ in 0..len {
+ let c_idx: u8 = rand::random::<u8>() % 36;
+
+ let c = if c_idx <= 10 {
+ (48 + c_idx) as char
+ } else {
+ ((c_idx - 10) + 65) as char
+ };
+
+ out.push(c)
+ }
+
+ out
+ }
+}
+
// position
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub struct IntPosition {
@@ -335,6 +439,20 @@ impl Deserialize for IntPosition {
}
}
+#[cfg(test)]
+impl TestRandom for IntPosition {
+ fn test_gen_random() -> Self {
+ let x: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25);
+ let z: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25);
+ let y: i16 = ((rand::random::<u16>() % (1 << 12)) as i16) - (1 << 11);
+ Self{
+ x,
+ y,
+ z
+ }
+ }
+}
+
// angle
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub struct Angle {
@@ -355,6 +473,15 @@ impl Deserialize for Angle {
}
}
+#[cfg(test)]
+impl TestRandom for Angle {
+ fn test_gen_random() -> Self {
+ Self{
+ value: rand::random()
+ }
+ }
+}
+
// UUID
impl Serialize for UUID4 {
@@ -388,6 +515,13 @@ impl Deserialize for UUID4 {
}
}
+#[cfg(test)]
+impl TestRandom for UUID4 {
+ fn test_gen_random() -> Self {
+ UUID4::random()
+ }
+}
+
// NBT
#[derive(Clone, PartialEq, Debug)]
@@ -420,6 +554,13 @@ impl Into<nbt::NamedTag> for NamedNbtTag {
}
}
+#[cfg(test)]
+impl TestRandom for NamedNbtTag {
+ fn test_gen_random() -> Self {
+ Self { root: nbt::NamedTag::test_gen_random() }
+ }
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FixedInt {
raw: i32
@@ -449,6 +590,13 @@ impl FixedInt {
}
}
+#[cfg(test)]
+impl TestRandom for FixedInt {
+ fn test_gen_random() -> Self {
+ FixedInt::new(f64::test_gen_random(), 16)
+ }
+}
+
// chat
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
pub struct Chat {
@@ -704,6 +852,19 @@ impl Chat {
to.push(formatter)
}
}
+
+ pub fn from_text(text: &str) -> Chat {
+ Chat{
+ text: text.to_owned(),
+ bold: None,
+ italic: None,
+ underlined: None,
+ strikethrough: None,
+ obfuscated: None,
+ color: None,
+ extra: None,
+ }
+ }
}
impl Serialize for Chat {
@@ -724,6 +885,14 @@ impl Deserialize for Chat {
}
}
+#[cfg(test)]
+impl TestRandom for Chat {
+ fn test_gen_random() -> Self {
+ let str = String::test_gen_random();
+ Chat::from_text(str.as_str())
+ }
+}
+
#[derive(Default)]
pub struct BytesSerializer {
data: Vec<u8>
@@ -774,6 +943,18 @@ impl<T> Deserialize for Option<T> where T: Deserialize {
}
}
+#[cfg(test)]
+impl<T> TestRandom for Option<T> where T: TestRandom {
+ fn test_gen_random() -> Self {
+ let is_present: bool = rand::random();
+ if is_present {
+ Some(T::test_gen_random())
+ } else {
+ None
+ }
+ }
+}
+
// SLOT
#[derive(Debug, PartialEq, Clone)]
pub struct Slot {
@@ -813,6 +994,21 @@ impl Deserialize for Slot {
}
#[cfg(test)]
+impl TestRandom for Slot {
+ fn test_gen_random() -> Self {
+ let item_id = VarInt::test_gen_random();
+ let item_count = i8::test_gen_random() % 65;
+ let nbt = <Option<nbt::NamedTag>>::test_gen_random();
+
+ Self{
+ item_id,
+ item_count,
+ nbt
+ }
+ }
+}
+
+#[cfg(test)]
mod tests {
use super::*;
use std::fmt::Debug;
diff --git a/src/v1_15_2.rs b/src/v1_15_2.rs
index d2ee960..1569d80 100644
--- a/src/v1_15_2.rs
+++ b/src/v1_15_2.rs
@@ -1,6 +1,9 @@
use crate::{*, uuid::*, types::*};
use std::fmt::Debug;
+#[cfg(test)]
+use crate::protocol::TestRandom;
+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum PacketDirection {
ClientBound,
@@ -804,56 +807,6 @@ proto_byte_enum!(HandshakeNextState,
0x02 :: Login
);
-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 }
- }
- }
- }
-}
-
#[inline]
fn varint_to_usize(v: VarInt) -> usize {
v.into()
@@ -927,6 +880,19 @@ impl From<Vec<u8>> for RemainingBytes {
}
}
+#[cfg(test)]
+impl TestRandom for RemainingBytes {
+ fn test_gen_random() -> Self {
+ let mut size: usize = rand::random::<usize>() % 256;
+ let mut out = Vec::with_capacity(size);
+ for _ in 0..size {
+ out.push(rand::random());
+ }
+
+ Self{ data: out }
+ }
+}
+
proto_byte_enum!(CardinalDirection,
0x00 :: South,
0x01 :: West,
@@ -1052,12 +1018,12 @@ proto_byte_enum!(ChatPosition,
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct BlockChangeHorizontalPosition {
pub rel_x: u8,
- pub rel_y: u8,
+ pub rel_z: u8,
}
impl Serialize for BlockChangeHorizontalPosition {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
- to.serialize_byte((self.rel_x & 0xF) << 4 | (self.rel_y & 0xF))
+ to.serialize_byte((self.rel_x & 0xF) << 4 | (self.rel_z & 0xF))
}
}
@@ -1066,12 +1032,22 @@ impl Deserialize for BlockChangeHorizontalPosition {
Ok(u8::mc_deserialize(data)?.map(move |b| {
BlockChangeHorizontalPosition {
rel_x: (b >> 4) & 0xF,
- rel_y: b & 0xF,
+ rel_z: b & 0xF,
}
}))
}
}
+#[cfg(test)]
+impl TestRandom for BlockChangeHorizontalPosition {
+ fn test_gen_random() -> Self {
+ BlockChangeHorizontalPosition{
+ rel_x: rand::random(),
+ rel_z: rand::random(),
+ }
+ }
+}
+
__protocol_body_def_helper!(MultiBlockChangeRecord {
horizontal_position: BlockChangeHorizontalPosition,
y_coordinate: u8,
@@ -1126,6 +1102,14 @@ impl Deserialize for BossBarAction {
}
}
+#[cfg(test)]
+impl TestRandom for BossBarAction {
+ fn test_gen_random() -> Self {
+ // todo
+ BossBarAction::Remove
+ }
+}
+
proto_varint_enum!(BossBarColor,
0x00 :: Pink,
0x01 :: Blue,
@@ -1322,6 +1306,14 @@ impl Deserialize for GameChangeReason {
}
}
+#[cfg(test)]
+impl TestRandom for GameChangeReason {
+ fn test_gen_random() -> Self {
+ // todo
+ GameChangeReason::PufferfishSting
+ }
+}
+
proto_varint_enum!(MapIconType,
0x00 :: WhiteArrow,
0x01 :: GreenArrow,
@@ -1414,6 +1406,13 @@ impl From<Option<MapColumnsSpec>> for MapColumns {
}
}
+#[cfg(test)]
+impl TestRandom for MapColumns {
+ fn test_gen_random() -> Self {
+ <Option<MapColumnsSpec>>::test_gen_random().into()
+ }
+}
+
__protocol_body_def_helper!(TradeSpec {
input_item_1: Option<Slot>,
output_item: Option<Slot>,
@@ -1516,6 +1515,13 @@ impl Deserialize for CombatEvent {
}
}
+#[cfg(test)]
+impl TestRandom for CombatEvent {
+ fn test_gen_random() -> Self {
+ CombatEvent::Enter // todo
+ }
+}
+
#[derive(Clone, PartialEq, Debug)]
pub struct PlayerInfoAction<A: Clone + PartialEq + Debug> {
pub uuid: UUID4,
@@ -1637,6 +1643,15 @@ impl Deserialize for PlayerInfoActionList {
}
}
+#[cfg(test)]
+impl TestRandom for PlayerInfoActionList {
+ fn test_gen_random() -> Self {
+ PlayerInfoActionList::Remove({
+ vec!(UUID4::random())
+ })
+ }
+}
+
fn serialize_vec_directly<I: Serialize, S: Serializer>(items: &Vec<I>, to: &mut S) -> SerializeResult {
for item in items {
to.serialize_other(item)?;
@@ -1801,6 +1816,15 @@ impl Deserialize for WorldBorderAction {
}
}
+#[cfg(test)]
+impl TestRandom for WorldBorderAction {
+ fn test_gen_random() -> Self {
+ WorldBorderAction::SetSize(WorldBorderSetSizeSpec{
+ diameter: f64::test_gen_random()
+ })
+ }
+}
+
#[derive(Clone, Copy, PartialEq, Debug, Eq)]
pub enum ScoreboardPosition {
List,
@@ -1847,6 +1871,13 @@ impl Deserialize for ScoreboardPosition {
}
}
+#[cfg(test)]
+impl TestRandom for ScoreboardPosition {
+ fn test_gen_random() -> Self {
+ ScoreboardPosition::Sidebar
+ }
+}
+
proto_varint_enum!(EquipmentSlot,
0x00 :: MainHand,
0x01 :: OffHand,
@@ -1911,6 +1942,13 @@ impl Deserialize for ScoreboardObjectiveAction {
}
}
+#[cfg(test)]
+impl TestRandom for ScoreboardObjectiveAction {
+ fn test_gen_random() -> Self {
+ ScoreboardObjectiveAction::Remove
+ }
+}
+
__protocol_body_def_helper!(EntityPropertySpec {
key: String,
value: f64,
@@ -2028,6 +2066,13 @@ impl Deserialize for InteractKind {
}
}
+#[cfg(test)]
+impl TestRandom for InteractKind {
+ fn test_gen_random() -> Self {
+ InteractKind::Attack
+ }
+}
+
proto_byte_flag!(ClientPlayerAbilities,
0x01 :: creative,
0x02 :: flying,
@@ -2241,6 +2286,16 @@ impl Deserialize for RecipeSpec {
}
}
+#[cfg(test)]
+impl TestRandom for RecipeSpec {
+ fn test_gen_random() -> Self {
+ RecipeSpec {
+ recipe: Recipe::CraftingRepairItem,
+ id: String::test_gen_random(),
+ }
+ }
+}
+
__protocol_body_def_helper!(RecipeIngredient {
items: VarIntCountedArray<Option<Slot>>
});
@@ -2292,6 +2347,19 @@ impl Deserialize for RecipeCraftingShapedSpec {
}
}
+#[cfg(test)]
+impl TestRandom for RecipeCraftingShapedSpec {
+ fn test_gen_random() -> Self {
+ RecipeCraftingShapedSpec {
+ width: VarInt::test_gen_random(),
+ height: VarInt::test_gen_random(),
+ group: String::test_gen_random(),
+ ingredients: vec!(RecipeIngredient::test_gen_random()),
+ result: <Option<Slot>>::test_gen_random(),
+ }
+ }
+}
+
__protocol_body_def_helper!(RecipeSmeltingSpec {
group: String,
ingredient: RecipeIngredient,
@@ -2388,4 +2456,498 @@ impl Deserialize for ChunkData {
block_entities,
}, data)
}
+}
+
+#[cfg(test)]
+impl TestRandom for ChunkData {
+ fn test_gen_random() -> Self {
+ ChunkData{
+ chunk_x: rand::random(),
+ chunk_z: rand::random(),
+ primary_bit_mask: VarInt::test_gen_random(),
+ heightmaps: NamedNbtTag::test_gen_random(),
+ biomes: None,
+ data: <VarIntCountedArray<u8>>::test_gen_random(),
+ block_entities: vec![]
+ }
+ }
+}
+
+#[cfg(test)]
+pub mod tests {
+
+ use super::*;
+ use crate::packet_test_cases;
+ use crate::protocol::{RawPacket, Packet};
+ use crate::types::BytesSerializer;
+ use crate::test_macros::BenchSerializer;
+ use test::Bencher;
+
+ packet_test_cases!(Packet578, Handshake, HandshakeSpec,
+ test_handshake, bench_write_handshake, bench_read_handshake);
+
+ packet_test_cases!(Packet578, StatusRequest, StatusRequestSpec,
+ test_status_request, bench_write_status_request, bench_read_status_request);
+
+ packet_test_cases!(Packet578, StatusPing, StatusPingSpec,
+ test_status_ping, bench_write_status_ping, bench_read_status_ping);
+
+ packet_test_cases!(Packet578, StatusResponse, StatusResponseSpec,
+ test_status_response, bench_write_status_response, bench_read_status_response);
+
+ packet_test_cases!(Packet578, StatusPong, StatusPongSpec,
+ test_status_pong, bench_write_status_pong, bench_read_status_pong);
+
+ packet_test_cases!(Packet578, LoginDisconnect, LoginDisconnectSpec,
+ test_login_disconnect, bench_write_login_disconnect, bench_read_login_disconnect);
+
+ packet_test_cases!(Packet578, LoginEncryptionRequest, LoginEncryptionRequestSpec,
+ test_login_encryption_request, bench_write_login_encryption_request, bench_read_login_encryption_request);
+
+ packet_test_cases!(Packet578, LoginSuccess, LoginSuccessSpec,
+ test_login_success, bench_write_login_success, bench_read_login_success);
+
+ packet_test_cases!(Packet578, LoginSetCompression, LoginSetCompressionSpec,
+ test_login_set_compression, bench_write_login_set_compression, bench_read_login_set_compression);
+
+ packet_test_cases!(Packet578, LoginPluginRequest, LoginPluginRequestSpec,
+ test_login_plugin_request, bench_write_login_plugin_request, bench_read_login_plugin_request);
+
+ packet_test_cases!(Packet578, LoginStart, LoginStartSpec,
+ test_login_start, bench_write_login_start, bench_read_login_start);
+
+ packet_test_cases!(Packet578, LoginEncryptionResponse, LoginEncryptionResponseSpec,
+ test_login_encryption_response, bench_write_login_encryption_response, bench_read_login_encryption_response);
+
+ packet_test_cases!(Packet578, LoginPluginResponse, LoginPluginResponseSpec,
+ test_login_plugin_response, bench_write_login_plugin_response, bench_read_login_plugin_response);
+
+ packet_test_cases!(Packet578, PlaySpawnEntity, PlaySpawnEntitySpec,
+ test_play_spawn_entity, bench_write_play_spawn_entity, bench_read_play_spawn_entity);
+
+ packet_test_cases!(Packet578, PlaySpawnExperienceOrb, PlaySpawnExperienceOrbSpec,
+ test_play_spawn_experience_orb, bench_write_play_spawn_experience_orb, bench_read_play_spawn_experience_orb);
+
+ packet_test_cases!(Packet578, PlaySpawnWeatherEntity, PlaySpawnWeatherEntitySpec,
+ test_play_spawn_weather_entity, bench_write_play_spawn_weather_entity, bench_read_play_spawn_weather_entity);
+
+ packet_test_cases!(Packet578, PlaySpawnLivingEntity, PlaySpawnLivingEntitySpec,
+ test_play_spawn_living_entity, bench_write_play_spawn_living_entity, bench_read_play_spawn_living_entity);
+
+ packet_test_cases!(Packet578, PlaySpawnPainting, PlaySpawnPaintingSpec,
+ test_play_spawn_painting, bench_write_play_spawn_painting, bench_read_play_spawn_painting);
+
+ packet_test_cases!(Packet578, PlaySpawnPlayer, PlaySpawnPlayerSpec,
+ test_play_spawn_player, bench_write_play_spawn_player, bench_read_play_spawn_player);
+
+ packet_test_cases!(Packet578, PlayEntityAnimation, PlayEntityAnimationSpec,
+ test_play_entity_animation, bench_write_play_entity_animation, bench_read_play_entity_animation);
+
+ packet_test_cases!(Packet578, PlayStatistics, PlayStatisticsSpec,
+ test_play_statistics, bench_write_play_statistics, bench_read_play_statistics);
+
+ packet_test_cases!(Packet578, PlayAcknowledgePlayerDigging, PlayAcknowledgePlayerDiggingSpec,
+ test_play_acknowledge_player_digging, bench_write_play_acknowledge_player_digging, bench_read_play_acknowledge_player_digging);
+
+ packet_test_cases!(Packet578, PlayBlockBreakAnimation, PlayBlockBreakAnimationSpec,
+ test_play_block_break_animation, bench_write_play_block_break_animation, bench_read_play_block_break_animation);
+
+ packet_test_cases!(Packet578, PlayBlockEntityData, PlayBlockEntityDataSpec,
+ test_play_block_entity_data, bench_write_play_block_entity_data, bench_read_play_block_entity_data);
+
+ packet_test_cases!(Packet578, PlayBlockAction, PlayBlockActionSpec,
+ test_play_block_action, bench_write_play_block_action, bench_read_play_block_action);
+
+ packet_test_cases!(Packet578, PlayBlockChange, PlayBlockChangeSpec,
+ test_play_block_change, bench_write_play_block_change, bench_read_play_block_change);
+
+ packet_test_cases!(Packet578, PlayBossBar, PlayBossBarSpec,
+ test_play_boss_bar, bench_write_play_boss_bar, bench_read_play_boss_bar);
+
+ packet_test_cases!(Packet578, PlayServerDifficulty, PlayServerDifficultySpec,
+ test_play_server_difficulty, bench_write_play_server_difficulty, bench_read_play_server_difficulty);
+
+ packet_test_cases!(Packet578, PlayServerChatMessage, PlayServerChatMessageSpec,
+ test_play_server_chat_message, bench_write_play_server_chat_message, bench_read_play_server_chat_message);
+
+ packet_test_cases!(Packet578, PlayMultiBlockChange, PlayMultiBlockChangeSpec,
+ test_play_multi_block_change, bench_write_play_multi_block_change, bench_read_play_multi_block_change);
+
+ packet_test_cases!(Packet578, PlayTabComplete, PlayTabCompleteSpec,
+ test_play_tab_complete, bench_write_play_tab_complete, bench_read_play_tab_complete);
+
+ packet_test_cases!(Packet578, PlayDeclareCommands, PlayDeclareCommandsSpec,
+ test_play_declare_commands, bench_write_play_declare_commands, bench_read_play_declare_commands);
+
+ packet_test_cases!(Packet578, PlayServerWindowConfirmation, PlayServerWindowConfirmationSpec,
+ test_play_server_window_confirmation, bench_write_play_server_window_confirmation, bench_read_play_server_window_confirmation);
+
+ packet_test_cases!(Packet578, PlayServerCloseWindow, PlayServerCloseWindowSpec,
+ test_play_server_close_window, bench_write_play_server_close_window, bench_read_play_server_close_window);
+
+ packet_test_cases!(Packet578, PlayWindowItems, PlayWindowItemsSpec,
+ test_play_window_items, bench_write_play_window_items, bench_read_play_window_items);
+
+ packet_test_cases!(Packet578, PlayWindowProperty, PlayWindowPropertySpec,
+ test_play_window_property, bench_write_play_window_property, bench_read_play_window_property);
+
+ packet_test_cases!(Packet578, PlaySetSlot, PlaySetSlotSpec,
+ test_play_set_slot, bench_write_play_set_slot, bench_read_play_set_slot);
+
+ packet_test_cases!(Packet578, PlaySetCooldown, PlaySetCooldownSpec,
+ test_play_set_cooldown, bench_write_play_set_cooldown, bench_read_play_set_cooldown);
+
+ packet_test_cases!(Packet578, PlayServerPluginMessage, PlayServerPluginMessageSpec,
+ test_play_server_plugin_message, bench_write_play_server_plugin_message, bench_read_play_server_plugin_message);
+
+ packet_test_cases!(Packet578, PlayNamedSoundEffect, PlayNamedSoundEffectSpec,
+ test_play_named_sound_effect, bench_write_play_named_sound_effect, bench_read_play_named_sound_effect);
+
+ packet_test_cases!(Packet578, PlayDisconnect, PlayDisconnectSpec,
+ test_play_disconnect, bench_write_play_disconnect, bench_read_play_disconnect);
+
+ packet_test_cases!(Packet578, PlayEntityStatus, PlayEntityStatusSpec,
+ test_play_entity_status, bench_write_play_entity_status, bench_read_play_entity_status);
+
+ packet_test_cases!(Packet578, PlayExposion, PlayExposionSpec,
+ test_play_exposion, bench_write_play_exposion, bench_read_play_exposion);
+
+ packet_test_cases!(Packet578, PlayUnloadChunk, PlayUnloadChunkSpec,
+ test_play_unload_chunk, bench_write_play_unload_chunk, bench_read_play_unload_chunk);
+
+ packet_test_cases!(Packet578, PlayChangeGameState, PlayChangeGameStateSpec,
+ test_play_change_game_state, bench_write_play_change_game_state, bench_read_play_change_game_state);
+
+ packet_test_cases!(Packet578, PlayOpenHorseWindow, PlayOpenHorseWindowSpec,
+ test_play_open_horse_window, bench_write_play_open_horse_window, bench_read_play_open_horse_window);
+
+ packet_test_cases!(Packet578, PlayServerKeepAlive, PlayServerKeepAliveSpec,
+ test_play_server_keep_alive, bench_write_play_server_keep_alive, bench_read_play_server_keep_alive);
+
+ packet_test_cases!(Packet578, PlayChunkData, PlayChunkDataWrapper,
+ test_play_chunk_data, bench_write_play_chunk_data, bench_read_play_chunk_data);
+
+ packet_test_cases!(Packet578, PlayEffect, PlayEffectSpec,
+ test_play_effect, bench_write_play_effect, bench_read_play_effect);
+
+ packet_test_cases!(Packet578, PlayParticle, PlayParticleSpec,
+ test_play_particle, bench_write_play_particle, bench_read_play_particle);
+
+ packet_test_cases!(Packet578, PlayUpdateLight, PlayUpdateLoightSpec,
+ test_play_update_light, bench_write_play_update_light, bench_read_play_update_light);
+
+ packet_test_cases!(Packet578, PlayJoinGame, PlayJoinGameSpec,
+ test_play_join_game, bench_write_play_join_game, bench_read_play_join_game);
+
+ packet_test_cases!(Packet578, PlayMapData, PlayMapDataSpec,
+ test_play_map_data, bench_write_play_map_data, bench_read_play_map_data);
+
+ packet_test_cases!(Packet578, PlayTradeList, PlayTradeListSpec,
+ test_play_trade_list, bench_write_play_trade_list, bench_read_play_trade_list);
+
+ packet_test_cases!(Packet578, PlayEntityPosition, PlayEntityPositionSpec,
+ test_play_entity_position, bench_write_play_entity_position, bench_read_play_entity_position);
+
+ packet_test_cases!(Packet578, PlayEntityPositionAndRotation, PlayEntityPositionAndRotationSpec,
+ test_play_entity_position_and_rotation, bench_write_play_entity_position_and_rotation, bench_read_play_entity_position_and_rotation);
+
+ packet_test_cases!(Packet578, PlayEntityRotation, PlayEntityRotationSpec,
+ test_play_entity_rotation, bench_write_play_entity_rotation, bench_read_play_entity_rotation);
+
+ packet_test_cases!(Packet578, PlayEntityMovement, PlayEntityMovementSpec,
+ test_play_entity_movement, bench_write_play_entity_movement, bench_read_play_entity_movement);
+
+ packet_test_cases!(Packet578, PlayServerVehicleMove, PlayEntityVehicleMoveSpec,
+ test_play_server_vehicle_move, bench_write_play_server_vehicle_move, bench_read_play_server_vehicle_move);
+
+ packet_test_cases!(Packet578, PlayOpenBook, PlayOpenBookSpec,
+ test_play_open_book, bench_write_play_open_book, bench_read_play_open_book);
+
+ packet_test_cases!(Packet578, PlayOpenWindow, PlayOpenWindowSpec,
+ test_play_open_window, bench_write_play_open_window, bench_read_play_open_window);
+
+ packet_test_cases!(Packet578, PlayOpenSignEditor, PlayOpenSignEditorSpec,
+ test_play_open_sign_editor, bench_write_play_open_sign_editor, bench_read_play_open_sign_editor);
+
+ packet_test_cases!(Packet578, PlayCraftRecipeResponse, PlayCraftRecipeResponseSpec,
+ test_play_craft_recipe_response, bench_write_play_craft_recipe_response, bench_read_play_craft_recipe_response);
+
+ packet_test_cases!(Packet578, PlayServerPlayerAbilities, PlayServerPlayerAbilitiesSpec,
+ test_play_server_player_abilities, bench_write_play_server_player_abilities, bench_read_play_server_player_abilities);
+
+ packet_test_cases!(Packet578, PlayCombatEvent, PlayCombatEventSpec,
+ test_play_combat_event, bench_write_play_combat_event, bench_read_play_combat_event);
+
+ packet_test_cases!(Packet578, PlayPlayerInfo, PlayPlayerInfoSpec,
+ test_play_player_info, bench_write_play_player_info, bench_read_play_player_info);
+
+ packet_test_cases!(Packet578, PlayFacePlayer, PlayFacePlayerSpec,
+ test_play_face_player, bench_write_play_face_player, bench_read_play_face_player);
+
+ packet_test_cases!(Packet578, PlayServerPlayerPositionAndLook, PlayServerPlayerPositionAndLookSpec,
+ test_play_server_player_position_and_look, bench_write_play_server_player_position_and_look, bench_read_play_server_player_position_and_look);
+
+ packet_test_cases!(Packet578, PlayUnlockRecipes, PlayUnlockRecipesSpec,
+ test_play_unlock_recipes, bench_write_play_unlock_recipes, bench_read_play_unlock_recipes);
+
+ packet_test_cases!(Packet578, PlayDestroyEntities, PlayDestroyEntitiesSpec,
+ test_play_destroy_entities, bench_write_play_destroy_entities, bench_read_play_destroy_entities);
+
+ packet_test_cases!(Packet578, PlayRemoveEntityEffect, PlayRemoveEntityEffectSpec,
+ test_play_remove_entity_effect, bench_write_play_remove_entity_effect, bench_read_play_remove_entity_effect);
+
+ packet_test_cases!(Packet578, PlayResourcePackSend, PlayResourcePackSendSpec,
+ test_play_resource_pack_send, bench_write_play_resource_pack_send, bench_read_play_resource_pack_send);
+
+ packet_test_cases!(Packet578, PlayRespawn, PlayRespawnSpec,
+ test_play_respawn, bench_write_play_respawn, bench_read_play_respawn);
+
+ packet_test_cases!(Packet578, PlayEntityHeadLook, PlayEntityHeadLookSpec,
+ test_play_entity_head_look, bench_write_play_entity_head_look, bench_read_play_entity_head_look);
+
+ packet_test_cases!(Packet578, PlaySelectAdvancementTab, PlaySelectAdvancementTabSpec,
+ test_play_select_advancement_tab, bench_write_play_select_advancement_tab, bench_read_play_select_advancement_tab);
+
+ packet_test_cases!(Packet578, PlayWorldBorder, PlayWorldBorderSpec,
+ test_play_world_border, bench_write_play_world_border, bench_read_play_world_border);
+
+ packet_test_cases!(Packet578, PlayCamera, PlayCameraSpec,
+ test_play_camera, bench_write_play_camera, bench_read_play_camera);
+
+ packet_test_cases!(Packet578, PlayServerHeldItemChange, PlayServerHeldItemChangeSpec,
+ test_play_server_held_item_change, bench_write_play_server_held_item_change, bench_read_play_server_held_item_change);
+
+ packet_test_cases!(Packet578, PlayUpdateViewPosition, PlayUpdateViewPositionSpec,
+ test_play_update_view_position, bench_write_play_update_view_position, bench_read_play_update_view_position);
+
+ packet_test_cases!(Packet578, PlayUpdateViewDistance, PlayUpdateViewDistanceSpec,
+ test_play_update_view_distance, bench_write_play_update_view_distance, bench_read_play_update_view_distance);
+
+ packet_test_cases!(Packet578, PlayDisplayScoreboard, PlayDisplayScoreboardSpec,
+ test_play_display_scoreboard, bench_write_play_display_scoreboard, bench_read_play_display_scoreboard);
+
+ packet_test_cases!(Packet578, PlayEntityMetadata, PlayEntityMetadataSpec,
+ test_play_entity_metadata, bench_write_play_entity_metadata, bench_read_play_entity_metadata);
+
+ packet_test_cases!(Packet578, PlayAttachEntity, PlayAttachEntitySpec,
+ test_play_attach_entity, bench_write_play_attach_entity, bench_read_play_attach_entity);
+
+ packet_test_cases!(Packet578, PlayEntityVelocity, PlayEntityVelocitySpec,
+ test_play_entity_velocity, bench_write_play_entity_velocity, bench_read_play_entity_velocity);
+
+ packet_test_cases!(Packet578, PlayEntityEquipment, PlayEntityEquiptmentSpec,
+ test_play_entity_equipment, bench_write_play_entity_equipment, bench_read_play_entity_equipment);
+
+ packet_test_cases!(Packet578, PlaySetExperience, PlaySetExperienceSpec,
+ test_play_set_experience, bench_write_play_set_experience, bench_read_play_set_experience);
+
+ packet_test_cases!(Packet578, PlayUpdatehealth, PlayUpdateHealthSpec,
+ test_play_updatehealth, bench_write_play_updatehealth, bench_read_play_updatehealth);
+
+ packet_test_cases!(Packet578, PlayScoreboardObjective, PlayScoreboardObjectiveSpec,
+ test_play_scoreboard_objective, bench_write_play_scoreboard_objective, bench_read_play_scoreboard_objective);
+
+ packet_test_cases!(Packet578, PlaySetPassengers, PlaySetPassengersSpec,
+ test_play_set_passengers, bench_write_play_set_passengers, bench_read_play_set_passengers);
+
+ packet_test_cases!(Packet578, PlaySpawnPosition, PlaySpawnPositionSpec,
+ test_play_spawn_position, bench_write_play_spawn_position, bench_read_play_spawn_position);
+
+ packet_test_cases!(Packet578, PlayTimeUpdate, PlayTimeUpdateSpec,
+ test_play_time_update, bench_write_play_time_update, bench_read_play_time_update);
+
+ packet_test_cases!(Packet578, PlayEntitySoundEffect, PlayEntitySoundEffectSpec,
+ test_play_entity_sound_effect, bench_write_play_entity_sound_effect, bench_read_play_entity_sound_effect);
+
+ packet_test_cases!(Packet578, PlaySoundEffect, PlaySoundEffectSpec,
+ test_play_sound_effect, bench_write_play_sound_effect, bench_read_play_sound_effect);
+
+ packet_test_cases!(Packet578, PlayerPlayerListHeaderAndFooter, PlayPlayerListHeaderAndFooterSpec,
+ test_player_player_list_header_and_footer, bench_write_player_player_list_header_and_footer, bench_read_player_player_list_header_and_footer);
+
+ packet_test_cases!(Packet578, PlayNbtQueryResponse, PlayNbtQueryResponseSpec,
+ test_play_nbt_query_response, bench_write_play_nbt_query_response, bench_read_play_nbt_query_response);
+
+ packet_test_cases!(Packet578, PlayCollectItem, PlayCollectItemSpec,
+ test_play_collect_item, bench_write_play_collect_item, bench_read_play_collect_item);
+
+ packet_test_cases!(Packet578, PlayEntityTeleport, PlayEntityTeleportSpec,
+ test_play_entity_teleport, bench_write_play_entity_teleport, bench_read_play_entity_teleport);
+
+ packet_test_cases!(Packet578, PlayAdvancements, PlayAdvancementsSpec,
+ test_play_advancements, bench_write_play_advancements, bench_read_play_advancements);
+
+ packet_test_cases!(Packet578, PlayEntityProperties, PlayEntityPropertiesSpec,
+ test_play_entity_properties, bench_write_play_entity_properties, bench_read_play_entity_properties);
+
+ packet_test_cases!(Packet578, PlayEntityEffect, PlayEntityEffectSpec,
+ test_play_entity_effect, bench_write_play_entity_effect, bench_read_play_entity_effect);
+
+ packet_test_cases!(Packet578, PlayDeclareRecipes, PlayDeclareRecipesSpec,
+ test_play_declare_recipes, bench_write_play_declare_recipes, bench_read_play_declare_recipes);
+
+ packet_test_cases!(Packet578, PlayTags, PlayTagsSpec,
+ test_play_tags, bench_write_play_tags, bench_read_play_tags);
+
+ packet_test_cases!(Packet578, PlayTeleportConfirm, PlayTeleportConfirmSpec,
+ test_play_teleport_confirm, bench_write_play_teleport_confirm, bench_read_play_teleport_confirm);
+
+ packet_test_cases!(Packet578, PlayQueryBlockNbt, PlayQueryBlockNbtSpec,
+ test_play_query_block_nbt, bench_write_play_query_block_nbt, bench_read_play_query_block_nbt);
+
+ packet_test_cases!(Packet578, PlayQueryEntityNbt, PlayQueryEntityNbtSpec,
+ test_play_query_entity_nbt, bench_write_play_query_entity_nbt, bench_read_play_query_entity_nbt);
+
+ packet_test_cases!(Packet578, PlaySetDifficulty, PlaySetDifficultySpec,
+ test_play_set_difficulty, bench_write_play_set_difficulty, bench_read_play_set_difficulty);
+
+ packet_test_cases!(Packet578, PlayClientChatMessage, PlayClientChatMessageSpec,
+ test_play_client_chat_message, bench_write_play_client_chat_message, bench_read_play_client_chat_message);
+
+ packet_test_cases!(Packet578, PlayClientStatus, PlayClientStatusSpec,
+ test_play_client_status, bench_write_play_client_status, bench_read_play_client_status);
+
+ packet_test_cases!(Packet578, PlayClientSettings, PlayClientSettingsSpec,
+ test_play_client_settings, bench_write_play_client_settings, bench_read_play_client_settings);
+
+ packet_test_cases!(Packet578, PlayClientTabComplete, PlayClientTabCompleteSpec,
+ test_play_client_tab_complete, bench_write_play_client_tab_complete, bench_read_play_client_tab_complete);
+
+ packet_test_cases!(Packet578, PlayClientWindowConfirmation, PlayClientWindowConfirmationSpec,
+ test_play_client_window_confirmation, bench_write_play_client_window_confirmation, bench_read_play_client_window_confirmation);
+
+ packet_test_cases!(Packet578, PlayClickWindowButton, PlayClickWindowButtonSpec,
+ test_play_click_window_button, bench_write_play_click_window_button, bench_read_play_click_window_button);
+
+ packet_test_cases!(Packet578, PlayClickWindow, PlayClickWindowSpec,
+ test_play_click_window, bench_write_play_click_window, bench_read_play_click_window);
+
+ packet_test_cases!(Packet578, PlayClientCloseWindow, PlayClientCloseWindowSpec,
+ test_play_client_close_window, bench_write_play_client_close_window, bench_read_play_client_close_window);
+
+ packet_test_cases!(Packet578, PlayClientPluginMessage, PlayClientPluginMessageSpec,
+ test_play_client_plugin_message, bench_write_play_client_plugin_message, bench_read_play_client_plugin_message);
+
+ packet_test_cases!(Packet578, PlayEditBook, PlayEditBookSpec,
+ test_play_edit_book, bench_write_play_edit_book, bench_read_play_edit_book);
+
+ packet_test_cases!(Packet578, PlayInteractEntity, PlayInteractEntitySpec,
+ test_play_interact_entity, bench_write_play_interact_entity, bench_read_play_interact_entity);
+
+ packet_test_cases!(Packet578, PlayClientKeepAlive, PlayClientKeepAliveSpec,
+ test_play_client_keep_alive, bench_write_play_client_keep_alive, bench_read_play_client_keep_alive);
+
+ packet_test_cases!(Packet578, PlayLockDifficulty, PlayLockDifficultySpec,
+ test_play_lock_difficulty, bench_write_play_lock_difficulty, bench_read_play_lock_difficulty);
+
+ packet_test_cases!(Packet578, PlayPlayerPosition, PlayPlayerPositionSpec,
+ test_play_player_position, bench_write_play_player_position, bench_read_play_player_position);
+
+ packet_test_cases!(Packet578, PlayClientPlayerPositionAndRotation, PlayClientPlayerPositionAndRotationSpec,
+ test_play_client_player_position_and_rotation, bench_write_play_client_player_position_and_rotation, bench_read_play_client_player_position_and_rotation);
+
+ packet_test_cases!(Packet578, PlayPlayerRotation, PlayPlayerRotationSpec,
+ test_play_player_rotation, bench_write_play_player_rotation, bench_read_play_player_rotation);
+
+ packet_test_cases!(Packet578, PlayPlayerMovement, PlayPlayerMovementSpec,
+ test_play_player_movement, bench_write_play_player_movement, bench_read_play_player_movement);
+
+ packet_test_cases!(Packet578, PlayClientVehicleMove, PlayClientVehicleMoveSpec,
+ test_play_client_vehicle_move, bench_write_play_client_vehicle_move, bench_read_play_client_vehicle_move);
+
+ packet_test_cases!(Packet578, PlaySteerBoat, PlaySteerBoatSpec,
+ test_play_steer_boat, bench_write_play_steer_boat, bench_read_play_steer_boat);
+
+ packet_test_cases!(Packet578, PlayPickItem, PlayPickItemSpec,
+ test_play_pick_item, bench_write_play_pick_item, bench_read_play_pick_item);
+
+ packet_test_cases!(Packet578, PlayCraftRecipeRequest, PlayCraftRecipeRequestSpec,
+ test_play_craft_recipe_request, bench_write_play_craft_recipe_request, bench_read_play_craft_recipe_request);
+
+ packet_test_cases!(Packet578, PlayClientPlayerAbilities, PlayClientPlayerAbilitiesSpec,
+ test_play_client_player_abilities, bench_write_play_client_player_abilities, bench_read_play_client_player_abilities);
+
+ packet_test_cases!(Packet578, PlayPlayerDigging, PlayPlayerDiggingSpec,
+ test_play_player_digging, bench_write_play_player_digging, bench_read_play_player_digging);
+
+ packet_test_cases!(Packet578, PlayEntityAction, PlayEntityActionSpec,
+ test_play_entity_action, bench_write_play_entity_action, bench_read_play_entity_action);
+
+ packet_test_cases!(Packet578, PlaySteerVehicle, PlaySteerVehicleSpec,
+ test_play_steer_vehicle, bench_write_play_steer_vehicle, bench_read_play_steer_vehicle);
+
+ packet_test_cases!(Packet578, PlayNameItem, PlayNameItemSpec,
+ test_play_name_item, bench_write_play_name_item, bench_read_play_name_item);
+
+ packet_test_cases!(Packet578, PlayResourcePackStatus, PlayResourcePackStatusSpec,
+ test_play_resource_pack_status, bench_write_play_resource_pack_status, bench_read_play_resource_pack_status);
+
+ packet_test_cases!(Packet578, PlaySelectTrade, PlaySelectTradeSpec,
+ test_play_select_trade, bench_write_play_select_trade, bench_read_play_select_trade);
+
+ packet_test_cases!(Packet578, PlaySetBeaconEffect, PlaySetBeaconEffectSpec,
+ test_play_set_beacon_effect, bench_write_play_set_beacon_effect, bench_read_play_set_beacon_effect);
+
+ packet_test_cases!(Packet578, PlayClientHeldItemChange, PlayClientHeldItemChangeSpec,
+ test_play_client_held_item_change, bench_write_play_client_held_item_change, bench_read_play_client_held_item_change);
+
+ packet_test_cases!(Packet578, PlayUpdateCommandBlock, PlayUpdateCommandBlockSpec,
+ test_play_update_command_block, bench_write_play_update_command_block, bench_read_play_update_command_block);
+
+ packet_test_cases!(Packet578, PlayUpdateCommandBlockMinecart, PlayUpdateCommandBlockMinecartSpec,
+ test_play_update_command_block_minecart, bench_write_play_update_command_block_minecart, bench_read_play_update_command_block_minecart);
+
+ packet_test_cases!(Packet578, PlayCreativeInventoryAction, PlayCreativeInventoryActionSpec,
+ test_play_creative_inventory_action, bench_write_play_creative_inventory_action, bench_read_play_creative_inventory_action);
+
+ packet_test_cases!(Packet578, PlayUpdateJigsawBlock, PlayUpdateJigsawBlockSpec,
+ test_play_update_jigsaw_block, bench_write_play_update_jigsaw_block, bench_read_play_update_jigsaw_block);
+
+ packet_test_cases!(Packet578, PlayUpdateStructureBlock, PlayUpdateStructureBlockSpec,
+ test_play_update_structure_block, bench_write_play_update_structure_block, bench_read_play_update_structure_block);
+
+ packet_test_cases!(Packet578, PlayUpdateSign, PlayUpdateSignSpec,
+ test_play_update_sign, bench_write_play_update_sign, bench_read_play_update_sign);
+
+ packet_test_cases!(Packet578, PlayClientAnimation, PlayClientAnimationSpec,
+ test_play_client_animation, bench_write_play_client_animation, bench_read_play_client_animation);
+
+ packet_test_cases!(Packet578, PlaySpectate, PlaySpectateSpec,
+ test_play_spectate, bench_write_play_spectate, bench_read_play_spectate);
+
+ packet_test_cases!(Packet578, PlayBlockPlacement, PlayBlockPlacementSpec,
+ test_play_block_placement, bench_write_play_block_placement, bench_read_play_block_placement);
+
+ packet_test_cases!(Packet578, PlayUseItem, PlayUseItemSpec,
+ test_play_use_item, bench_write_play_use_item, bench_read_play_use_item);
+
+ #[test]
+ fn test_generate_test_cases() {
+ Packet578::describe().packets.iter().map(move |packet| {
+ let snake_case = to_snake_case(packet.name.clone());
+ format!("packet_test_cases!(Packet578, {}, {},\n test_{}, bench_write_{}, bench_read_{});\n",
+ packet.name, packet.body_struct, snake_case, snake_case, snake_case).to_owned()
+ }).for_each(move |line| {
+ println!("{}", line)
+ })
+ }
+
+ fn to_snake_case(camel: String) -> String {
+ let mut parts = Vec::new();
+ let mut buf = String::new();
+ for c in camel.chars() {
+ if !buf.is_empty() && char::is_uppercase(c) {
+ parts.push(buf);
+ buf = String::new();
+ }
+
+ buf.push(c.to_ascii_lowercase());
+ }
+
+ if !buf.is_empty() {
+ parts.push(buf);
+ }
+
+ parts.join("_")
+ }
} \ No newline at end of file