From ccd8647113c8969ea6d8e403565c9ed223688730 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sat, 23 Jan 2021 18:39:59 +0300 Subject: [PATCH 01/22] Fix derive --- protocol-derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol-derive/src/lib.rs b/protocol-derive/src/lib.rs index 2953b8f..017e9db 100644 --- a/protocol-derive/src/lib.rs +++ b/protocol-derive/src/lib.rs @@ -5,7 +5,7 @@ use proc_macro2::Ident; use proc_macro2::TokenStream as TokenStream2; use quote::{quote, TokenStreamExt}; use std::iter::FromIterator; -use syn::export::Span; +use syn::__private::Span; use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, Lit, Meta, NestedMeta}; #[proc_macro_derive(Packet, attributes(packet))] From 284948356206df803703b91b40bdc9bbb373cc45 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sat, 23 Jan 2021 18:40:28 +0300 Subject: [PATCH 02/22] Add protocol state enum generation --- Cargo.toml | 1 + protocol-derive/Cargo.toml | 2 +- protocol-generator/Cargo.toml | 16 ++ protocol-generator/src/main.rs | 197 ++++++++++++++++++ .../templates/protocol_state_enum.hbs | 27 +++ 5 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 protocol-generator/Cargo.toml create mode 100644 protocol-generator/src/main.rs create mode 100644 protocol-generator/templates/protocol_state_enum.hbs diff --git a/Cargo.toml b/Cargo.toml index 4436a00..bfc5733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,5 @@ members = [ "protocol", "protocol-derive", + "protocol-generator" ] \ No newline at end of file diff --git a/protocol-derive/Cargo.toml b/protocol-derive/Cargo.toml index 8225931..b8e8f32 100644 --- a/protocol-derive/Cargo.toml +++ b/protocol-derive/Cargo.toml @@ -7,7 +7,7 @@ description = "Derive macro for reading and writing Minecraft packets" license = "MIT" homepage = "https://github.com/eihwaz/minecraft-protocol" repository = "https://github.com/eihwaz/minecraft-protocol" -keywords = ["minecraft", "protocol", "packet", "io"] +keywords = ["minecraft", "derive", "protocol", "packet", "io"] [lib] proc-macro = true diff --git a/protocol-generator/Cargo.toml b/protocol-generator/Cargo.toml new file mode 100644 index 0000000..47169da --- /dev/null +++ b/protocol-generator/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "minecraft-protocol-generator" +version = "0.0.0" +authors = ["vagola "] +edition = "2018" +description = "CLI for generating Rust code with Minecraft packets" +license = "MIT" +homepage = "https://github.com/eihwaz/minecraft-protocol" +repository = "https://github.com/eihwaz/minecraft-protocol" +keywords = ["minecraft", "cli", "protocol", "packet", "io"] + +[dependencies] +clap = "2.33.3" +serde = "1.0.120" +serde_json = "1.0" +handlebars = "3.5.2" diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs new file mode 100644 index 0000000..b6b0d5a --- /dev/null +++ b/protocol-generator/src/main.rs @@ -0,0 +1,197 @@ +use handlebars::{Handlebars, TemplateRenderError}; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use std::fmt; +use std::fmt::Display; +use std::fs::File; +use std::io::{BufWriter, Read}; + +enum State { + Handshake, + Status, + Login, + Game, +} + +impl Display for State { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + State::Handshake => "Handshake", + State::Status => "Status", + State::Login => "Login", + State::Game => "Game", + }; + + write!(f, "{}", name) + } +} + +enum Bound { + Server, + Client, +} + +impl Display for Bound { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + Bound::Server => "Server", + Bound::Client => "Client", + }; + + write!(f, "{}", name) + } +} + +#[derive(Serialize)] +struct Packet { + name: String, + fields: Vec, +} + +impl Packet { + pub fn new(name: impl ToString, fields: Vec) -> Packet { + Packet { + name: name.to_string(), + fields, + } + } +} + +#[derive(Serialize)] +struct Field { + name: String, + #[serde(rename(serialize = "type"))] + data_type: DataType, +} + +impl Field { + pub fn new(name: impl ToString, data_type: DataType) -> Field { + Field { + name: name.to_string(), + data_type, + } + } +} + +#[derive(Serialize)] +enum DataType { + Boolean, + Byte, + UnsignedByte, + Short, + UnsignedShort, + Int, + Long, + Float, + Double, + String, + Chat, + VarInt, + VarLong, + ByteArray, +} + +struct Protocol { + state: State, + server_bound_packets: Vec, + client_bound_packets: Vec, +} + +impl Protocol { + pub fn new( + state: State, + server_bound_packets: Vec, + client_bound_packets: Vec, + ) -> Protocol { + Protocol { + state, + server_bound_packets, + client_bound_packets, + } + } + + pub fn generate_rust_file( + &self, + template_engine: &Handlebars, + writer: &mut BufWriter<&File>, + ) -> Result<(), TemplateRenderError> { + write_protocol_enum( + writer, + &template_engine, + &self.server_bound_packets, + &Bound::Server, + &self.state, + )?; + + write_protocol_enum( + writer, + &template_engine, + &self.client_bound_packets, + &Bound::Client, + &self.state, + )?; + + Ok(()) + } +} + +fn write_protocol_enum( + writer: &mut BufWriter<&File>, + template_engine: &Handlebars, + packets: &Vec, + bound: &Bound, + state: &State, +) -> Result<(), TemplateRenderError> { + if !packets.is_empty() { + let enum_name = format!("{}{}BoundPacket", state, bound); + + let data = json!({ + "protocol_state_name": enum_name, + "packets": &packets + }); + + template_engine.render_to_write("protocol_state_enum", &data, writer)?; + } + + Ok(()) +} + +pub fn main() { + let mut template_engine = Handlebars::new(); + + template_engine + .register_template_file( + "protocol_state_enum", + "protocol-generator/templates/protocol_state_enum.hbs", + ) + .expect("Failed to register template"); + + let protocol = Protocol::new( + State::Login, + vec![ + Packet::new("LoginStart", vec![Field::new("name", DataType::String)]), + Packet::new( + "EncryptionResponse", + vec![ + Field::new("shared_secret", DataType::ByteArray), + Field::new("verify_token", DataType::ByteArray), + ], + ), + Packet::new("LoginPluginResponse", vec![]), + ], + vec![ + Packet::new("LoginDisconnect", vec![]), + Packet::new("EncryptionRequest", vec![]), + Packet::new("LoginSuccess", vec![]), + Packet::new("SetCompression", vec![]), + Packet::new("LoginPluginRequest", vec![]), + ], + ); + + let file = File::create("login.rs").expect("Failed to create file"); + let mut writer = BufWriter::new(&file); + + protocol + .generate_rust_file(&template_engine, &mut writer) + .expect("Failed to generate rust file"); +} diff --git a/protocol-generator/templates/protocol_state_enum.hbs b/protocol-generator/templates/protocol_state_enum.hbs new file mode 100644 index 0000000..ed31718 --- /dev/null +++ b/protocol-generator/templates/protocol_state_enum.hbs @@ -0,0 +1,27 @@ + +pub enum {{protocol_state_name}} { +{{~#each packets as |p|}} + {{p.name}}{{#unless @last}},{{/unless}} +{{~/each}} +} + +impl {{protocol_state_name}} { + pub fn get_type_id(&self) -> u8 { + match self { + {{~#each packets as |p|}} + Self::{{p.name}} => {{@index}}{{#unless @last}},{{/unless}} + {{~/each}} + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + {{~#each packets as |p|}} + {{@index}} => { + Ok(Self::{{p.name}}) + } + {{~/each}} + _ => Err(DecodeError::UnknownPacketType { type_id }) + } + } +} From 02f2d6b860f9b6108422a055e9185569c2ba1f3b Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 24 Jan 2021 01:03:16 +0300 Subject: [PATCH 03/22] Add protocol state structs and imports generation --- protocol-generator/Cargo.toml | 1 + protocol-generator/src/data.rs | 149 ++++++++ protocol-generator/src/main.rs | 327 +++++++++--------- .../templates/protocol_enum.hbs | 50 +++ .../templates/protocol_imports.hbs | 3 + .../templates/protocol_state_enum.hbs | 27 -- .../templates/protocol_structs.hbs | 24 ++ 7 files changed, 387 insertions(+), 194 deletions(-) create mode 100644 protocol-generator/src/data.rs create mode 100644 protocol-generator/templates/protocol_enum.hbs create mode 100644 protocol-generator/templates/protocol_imports.hbs delete mode 100644 protocol-generator/templates/protocol_state_enum.hbs create mode 100644 protocol-generator/templates/protocol_structs.hbs diff --git a/protocol-generator/Cargo.toml b/protocol-generator/Cargo.toml index 47169da..a4fd963 100644 --- a/protocol-generator/Cargo.toml +++ b/protocol-generator/Cargo.toml @@ -14,3 +14,4 @@ clap = "2.33.3" serde = "1.0.120" serde_json = "1.0" handlebars = "3.5.2" +heck = "0.3.2" diff --git a/protocol-generator/src/data.rs b/protocol-generator/src/data.rs new file mode 100644 index 0000000..8249979 --- /dev/null +++ b/protocol-generator/src/data.rs @@ -0,0 +1,149 @@ +use serde::Serialize; +use std::fmt; +use std::fmt::Display; + +pub enum State { + Handshake, + Status, + Login, + Game, +} + +impl Display for State { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + State::Handshake => "Handshake", + State::Status => "Status", + State::Login => "Login", + State::Game => "Game", + }; + + write!(f, "{}", name) + } +} + +pub enum Bound { + Server, + Client, +} + +impl Display for Bound { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let name = match self { + Bound::Server => "Server", + Bound::Client => "Client", + }; + + write!(f, "{}", name) + } +} + +#[derive(Serialize)] +pub struct Packet { + pub name: String, + pub fields: Vec, +} + +impl Packet { + pub fn new(name: impl ToString, fields: Vec) -> Packet { + Packet { + name: name.to_string(), + fields, + } + } +} + +#[derive(Serialize)] +pub struct Field { + pub name: String, + #[serde(flatten)] + pub data_type: DataType, +} + +impl Field { + pub fn new(name: impl ToString, data_type: DataType) -> Field { + Field { + name: name.to_string(), + data_type, + } + } +} + +#[derive(Serialize, Eq, PartialEq)] +#[serde(tag = "type")] +pub enum DataType { + #[serde(rename(serialize = "bool"))] + Boolean, + #[serde(rename(serialize = "i8"))] + Byte, + #[serde(rename(serialize = "u8"))] + UnsignedByte, + #[serde(rename(serialize = "i16"))] + Short, + #[serde(rename(serialize = "u16"))] + UnsignedShort, + #[serde(rename(serialize = "i32"))] + Int { + var_int: bool, + }, + #[serde(rename(serialize = "i64"))] + Long { + var_long: bool, + }, + #[serde(rename(serialize = "f32"))] + Float, + #[serde(rename(serialize = "f64"))] + Double, + String { + max_length: u16, + }, + Uuid { + hyphenated: bool, + }, + #[serde(rename(serialize = "Vec"))] + ByteArray { + rest: bool, + }, + CompoundTag, + RefType { + ref_name: String, + }, +} + +pub struct Protocol { + pub state: State, + pub server_bound_packets: Vec, + pub client_bound_packets: Vec, +} + +impl Protocol { + pub fn new( + state: State, + server_bound_packets: Vec, + client_bound_packets: Vec, + ) -> Protocol { + Protocol { + state, + server_bound_packets, + client_bound_packets, + } + } + + pub fn contains_field_with_type(&self, data_type: DataType) -> bool { + self.server_bound_packets + .iter() + .chain(self.client_bound_packets.iter()) + .flat_map(|p| p.fields.iter()) + .find(|f| f.data_type == data_type) + .is_some() + } + + pub fn contains_field_with_predicate bool>(&self, fun: F) -> bool { + self.server_bound_packets + .iter() + .chain(self.client_bound_packets.iter()) + .flat_map(|p| p.fields.iter()) + .find(|f| fun(*f)) + .is_some() + } +} diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index b6b0d5a..1634df7 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -1,197 +1,190 @@ -use handlebars::{Handlebars, TemplateRenderError}; -use serde::{Deserialize, Serialize}; +mod data; + +use crate::data::*; +use handlebars::*; +use heck::SnakeCase; +use serde::Serialize; use serde_json::json; -use std::fmt; -use std::fmt::Display; use std::fs::File; -use std::io::{BufWriter, Read}; - -enum State { - Handshake, - Status, - Login, - Game, -} - -impl Display for State { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = match self { - State::Handshake => "Handshake", - State::Status => "Status", - State::Login => "Login", - State::Game => "Game", - }; - - write!(f, "{}", name) - } -} - -enum Bound { - Server, - Client, -} - -impl Display for Bound { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = match self { - Bound::Server => "Server", - Bound::Client => "Client", - }; - - write!(f, "{}", name) - } -} - -#[derive(Serialize)] -struct Packet { - name: String, - fields: Vec, -} - -impl Packet { - pub fn new(name: impl ToString, fields: Vec) -> Packet { - Packet { - name: name.to_string(), - fields, - } - } -} - -#[derive(Serialize)] -struct Field { - name: String, - #[serde(rename(serialize = "type"))] - data_type: DataType, -} +use std::io::Write; -impl Field { - pub fn new(name: impl ToString, data_type: DataType) -> Field { - Field { - name: name.to_string(), - data_type, - } - } -} - -#[derive(Serialize)] -enum DataType { - Boolean, - Byte, - UnsignedByte, - Short, - UnsignedShort, - Int, - Long, - Float, - Double, - String, - Chat, - VarInt, - VarLong, - ByteArray, -} - -struct Protocol { - state: State, - server_bound_packets: Vec, - client_bound_packets: Vec, -} - -impl Protocol { - pub fn new( - state: State, - server_bound_packets: Vec, - client_bound_packets: Vec, - ) -> Protocol { - Protocol { - state, - server_bound_packets, - client_bound_packets, - } - } - - pub fn generate_rust_file( - &self, - template_engine: &Handlebars, - writer: &mut BufWriter<&File>, - ) -> Result<(), TemplateRenderError> { - write_protocol_enum( - writer, - &template_engine, - &self.server_bound_packets, - &Bound::Server, - &self.state, - )?; - - write_protocol_enum( - writer, - &template_engine, - &self.client_bound_packets, - &Bound::Client, - &self.state, - )?; - - Ok(()) - } -} - -fn write_protocol_enum( - writer: &mut BufWriter<&File>, - template_engine: &Handlebars, - packets: &Vec, - bound: &Bound, - state: &State, -) -> Result<(), TemplateRenderError> { - if !packets.is_empty() { - let enum_name = format!("{}{}BoundPacket", state, bound); - - let data = json!({ - "protocol_state_name": enum_name, - "packets": &packets - }); +pub fn main() { + let mut template_engine = Handlebars::new(); - template_engine.render_to_write("protocol_state_enum", &data, writer)?; - } + template_engine.register_helper("snake_case", Box::new(format_snake_case)); + template_engine.register_helper("packet_id", Box::new(format_packet_id)); + template_engine.register_escape_fn(|s| s.to_owned()); - Ok(()) -} + template_engine + .register_template_file( + "protocol_imports", + "protocol-generator/templates/protocol_imports.hbs", + ) + .expect("Failed to register template"); -pub fn main() { - let mut template_engine = Handlebars::new(); + template_engine + .register_template_file( + "protocol_enum", + "protocol-generator/templates/protocol_enum.hbs", + ) + .expect("Failed to register template"); template_engine .register_template_file( - "protocol_state_enum", - "protocol-generator/templates/protocol_state_enum.hbs", + "protocol_structs", + "protocol-generator/templates/protocol_structs.hbs", ) .expect("Failed to register template"); let protocol = Protocol::new( State::Login, vec![ - Packet::new("LoginStart", vec![Field::new("name", DataType::String)]), + Packet::new( + "LoginStart", + vec![Field::new("name", DataType::String { max_length: 256 })], + ), Packet::new( "EncryptionResponse", vec![ - Field::new("shared_secret", DataType::ByteArray), - Field::new("verify_token", DataType::ByteArray), + Field::new("shared_secret", DataType::ByteArray { rest: true }), + Field::new("verify_token", DataType::ByteArray { rest: true }), + ], + ), + Packet::new( + "LoginPluginResponse", + vec![ + Field::new("message_id", DataType::Int { var_int: true }), + Field::new("successful", DataType::Boolean), + Field::new("data", DataType::ByteArray { rest: true }), ], ), - Packet::new("LoginPluginResponse", vec![]), ], vec![ - Packet::new("LoginDisconnect", vec![]), - Packet::new("EncryptionRequest", vec![]), - Packet::new("LoginSuccess", vec![]), + Packet::new( + "LoginDisconnect", + vec![ + Field::new("hyphenated", DataType::Uuid { hyphenated: true }), + Field::new("default", DataType::Uuid { hyphenated: false }), + ], + ), + Packet::new( + "EncryptionRequest", + vec![Field::new( + "game_mode", + DataType::RefType { + ref_name: "GameMode".to_string(), + }, + )], + ), + Packet::new( + "LoginSuccess", + vec![Field::new( + "server_status", + DataType::RefType { + ref_name: "ServerStatus".to_string(), + }, + )], + ), Packet::new("SetCompression", vec![]), Packet::new("LoginPluginRequest", vec![]), ], ); let file = File::create("login.rs").expect("Failed to create file"); - let mut writer = BufWriter::new(&file); - protocol - .generate_rust_file(&template_engine, &mut writer) - .expect("Failed to generate rust file"); + generate_rust_file(&protocol, &template_engine, &file).expect("Failed to generate rust file"); +} + +#[derive(Serialize)] +struct GenerateContext<'a> { + protocol_enum_name: String, + packets: &'a Vec, +} + +pub fn generate_rust_file( + protocol: &Protocol, + template_engine: &Handlebars, + mut writer: W, +) -> Result<(), TemplateRenderError> { + let server_bound_ctx = GenerateContext { + protocol_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Server), + packets: &protocol.server_bound_packets, + }; + + let client_bound_ctx = GenerateContext { + protocol_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Client), + packets: &protocol.client_bound_packets, + }; + + let mut imports = vec![ + "crate::DecodeError", + "crate::Decoder", + "std::io::Read", + "minecraft_protocol_derive::Packet", + ]; + + if protocol.contains_field_with_predicate(|f| match f.data_type { + DataType::Uuid { .. } => true, + _ => false, + }) { + imports.push("uuid::Uuid") + } + + if protocol.contains_field_with_type(DataType::CompoundTag) { + imports.push("nbt::CompoundTag") + } + + template_engine.render_to_write( + "protocol_imports", + &json!({ "imports": imports }), + &mut writer, + )?; + + template_engine.render_to_write("protocol_enum", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("protocol_enum", &client_bound_ctx, &mut writer)?; + + template_engine.render_to_write("protocol_structs", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("protocol_structs", &client_bound_ctx, &mut writer)?; + + Ok(()) +} + +fn format_snake_case( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output, +) -> Result<(), RenderError> { + let str = h + .param(0) + .and_then(|v| v.value().as_str()) + .ok_or(RenderError::new( + "Param 0 with str type is required for snake case helper.", + ))? as &str; + + let snake_case_str = str.to_snake_case(); + + out.write(snake_case_str.as_ref())?; + Ok(()) +} + +fn format_packet_id( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output, +) -> Result<(), RenderError> { + let id = h + .param(0) + .and_then(|v| v.value().as_u64()) + .ok_or(RenderError::new( + "Param 0 with u64 type is required for packet id helper.", + ))? as u64; + + let packet_id_str = format!("{:#04X}", id); + + out.write(packet_id_str.as_ref())?; + Ok(()) } diff --git a/protocol-generator/templates/protocol_enum.hbs b/protocol-generator/templates/protocol_enum.hbs new file mode 100644 index 0000000..7915ecc --- /dev/null +++ b/protocol-generator/templates/protocol_enum.hbs @@ -0,0 +1,50 @@ + +pub enum {{protocol_enum_name}} { +{{~#each packets as |p|}} + {{p.name}}{{#if p.fields}}({{p.name}}){{/if}}{{#unless @last}},{{/unless}} +{{~/each}} +} + +impl {{protocol_enum_name}} { + pub fn get_type_id(&self) -> u8 { + match self { + {{~#each packets as |p|}} + Self::{{p.name}}{{#if p.fields}}(_){{/if}} => {{packet_id @index}}{{#unless @last}},{{/unless}} + {{~/each}} + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + {{~#each packets as |p|}} + {{@index}} => { + {{~#if p.fields}} + let {{snake_case p.name}} = {{p.name}}::decode(reader)?; + + Ok(Self::{{p.name}}({{snake_case p.name}})) + {{~/if}} + {{~#unless p.fields}} + Ok(Self::{{p.name}}) + {{~/unless}} + } + {{~/each}} + _ => Err(DecodeError::UnknownPacketType { type_id }) + } + } +{{#each packets as |p|}} + pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{f.type}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { + {{~#if p.fields}} + let {{snake_case p.name}} = {{p.name}} { + {{~#each p.fields as |f|}} + {{f.name}}{{#unless @last}},{{/unless}} + {{~/each}} + }; + + Self::{{p.name}}({{snake_case p.name}}) + {{~/if}} + {{~#unless p.fields}} + Self::{{p.name}} + {{~/unless}} + } +{{/each~}} +} diff --git a/protocol-generator/templates/protocol_imports.hbs b/protocol-generator/templates/protocol_imports.hbs new file mode 100644 index 0000000..03e74a9 --- /dev/null +++ b/protocol-generator/templates/protocol_imports.hbs @@ -0,0 +1,3 @@ +{{#each imports as |i|~}} +use {{i}}; +{{/each}} diff --git a/protocol-generator/templates/protocol_state_enum.hbs b/protocol-generator/templates/protocol_state_enum.hbs deleted file mode 100644 index ed31718..0000000 --- a/protocol-generator/templates/protocol_state_enum.hbs +++ /dev/null @@ -1,27 +0,0 @@ - -pub enum {{protocol_state_name}} { -{{~#each packets as |p|}} - {{p.name}}{{#unless @last}},{{/unless}} -{{~/each}} -} - -impl {{protocol_state_name}} { - pub fn get_type_id(&self) -> u8 { - match self { - {{~#each packets as |p|}} - Self::{{p.name}} => {{@index}}{{#unless @last}},{{/unless}} - {{~/each}} - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - {{~#each packets as |p|}} - {{@index}} => { - Ok(Self::{{p.name}}) - } - {{~/each}} - _ => Err(DecodeError::UnknownPacketType { type_id }) - } - } -} diff --git a/protocol-generator/templates/protocol_structs.hbs b/protocol-generator/templates/protocol_structs.hbs new file mode 100644 index 0000000..c6d4822 --- /dev/null +++ b/protocol-generator/templates/protocol_structs.hbs @@ -0,0 +1,24 @@ +{{~#each packets as |p|}} +{{~#if p.fields}} +#[derive(Packet, Debug)] +pub struct {{p.name}} { +{{~#each p.fields as |f|}} + {{~#if f.var_int}} + #[packet(with = "var_int")]{{/if}} + {{~#if f.var_long}} + #[packet(with = "var_long")]{{/if}} + {{~#if f.rest}} + #[packet(with = "rest")]{{/if}} + {{~#if f.hyphenated}} + #[packet(with = "uuid_hyp_str")]{{/if}} + {{~#if f.max_length}} + #[packet(max_length = {{f.max_length}})]{{/if}} + {{~#if (ne f.type "RefType")}} + pub {{f.name}}: {{f.type}}{{#unless @last}},{{/unless}} + {{~else}} + pub {{f.name}}: {{f.ref_name}}{{#unless @last}},{{/unless}} + {{~/if}} +{{~/each}} +} +{{/if}} +{{~/each}} From fca5351977ffa20f42c370f0a87be1423c14ccb7 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 24 Jan 2021 02:06:31 +0300 Subject: [PATCH 04/22] Refactor protocol and refactor imports --- Cargo.toml | 2 +- protocol-generator/src/data.rs | 40 +- protocol-generator/src/main.rs | 11 +- protocol/src/{ => data}/chat.rs | 50 +- protocol/src/data/game.rs | 22 + protocol/src/data/mod.rs | 3 + protocol/src/data/status.rs | 32 ++ protocol/src/error.rs | 106 ++++ protocol/src/game.rs | 504 ------------------ protocol/src/lib.rs | 137 +---- protocol/src/login.rs | 479 ----------------- protocol/src/packet/game.rs | 140 +++++ protocol/src/packet/login.rs | 159 ++++++ protocol/src/packet/mod.rs | 3 + protocol/src/packet/status.rs | 60 +++ protocol/src/status.rs | 235 -------- protocol/test/packet/game/chunk_data.dat | Bin 52 -> 0 bytes .../packet/game/client_bound_chat_message.dat | 1 - .../packet/game/client_bound_keep_alive.dat | Bin 8 -> 0 bytes protocol/test/packet/game/game_disconnect.dat | 1 - protocol/test/packet/game/join_game.dat | Bin 20 -> 0 bytes .../packet/game/server_bound_chat_message.dat | 1 - .../packet/game/server_bound_keep_alive.dat | Bin 8 -> 0 bytes .../test/packet/login/encryption_request.dat | 3 - .../test/packet/login/encryption_response.dat | 3 - .../test/packet/login/login_disconnect.dat | 1 - .../packet/login/login_plugin_request.dat | 1 - .../packet/login/login_plugin_response.dat | 1 - .../packet/login/login_set_compression.dat | 1 - protocol/test/packet/login/login_start.dat | 1 - protocol/test/packet/login/login_success.dat | 1 - protocol/test/packet/status/ping_request.dat | Bin 8 -> 0 bytes protocol/test/packet/status/ping_response.dat | Bin 8 -> 0 bytes .../test/packet/status/status_response.dat | 1 - 34 files changed, 598 insertions(+), 1401 deletions(-) rename protocol/src/{ => data}/chat.rs (90%) create mode 100644 protocol/src/data/game.rs create mode 100644 protocol/src/data/mod.rs create mode 100644 protocol/src/data/status.rs create mode 100644 protocol/src/error.rs delete mode 100644 protocol/src/game.rs delete mode 100644 protocol/src/login.rs create mode 100644 protocol/src/packet/game.rs create mode 100644 protocol/src/packet/login.rs create mode 100644 protocol/src/packet/mod.rs create mode 100644 protocol/src/packet/status.rs delete mode 100644 protocol/src/status.rs delete mode 100644 protocol/test/packet/game/chunk_data.dat delete mode 100644 protocol/test/packet/game/client_bound_chat_message.dat delete mode 100644 protocol/test/packet/game/client_bound_keep_alive.dat delete mode 100644 protocol/test/packet/game/game_disconnect.dat delete mode 100644 protocol/test/packet/game/join_game.dat delete mode 100644 protocol/test/packet/game/server_bound_chat_message.dat delete mode 100644 protocol/test/packet/game/server_bound_keep_alive.dat delete mode 100644 protocol/test/packet/login/encryption_request.dat delete mode 100644 protocol/test/packet/login/encryption_response.dat delete mode 100644 protocol/test/packet/login/login_disconnect.dat delete mode 100644 protocol/test/packet/login/login_plugin_request.dat delete mode 100644 protocol/test/packet/login/login_plugin_response.dat delete mode 100644 protocol/test/packet/login/login_set_compression.dat delete mode 100644 protocol/test/packet/login/login_start.dat delete mode 100644 protocol/test/packet/login/login_success.dat delete mode 100644 protocol/test/packet/status/ping_request.dat delete mode 100644 protocol/test/packet/status/ping_response.dat delete mode 100644 protocol/test/packet/status/status_response.dat diff --git a/Cargo.toml b/Cargo.toml index bfc5733..3107f43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,4 @@ members = [ "protocol", "protocol-derive", "protocol-generator" -] \ No newline at end of file +] diff --git a/protocol-generator/src/data.rs b/protocol-generator/src/data.rs index 8249979..0f85027 100644 --- a/protocol-generator/src/data.rs +++ b/protocol-generator/src/data.rs @@ -1,4 +1,5 @@ use serde::Serialize; +use std::collections::HashSet; use std::fmt; use std::fmt::Display; @@ -9,6 +10,17 @@ pub enum State { Game, } +impl State { + pub fn data_import(&self) -> &str { + match self { + State::Handshake => "crate::packet::handshake", + State::Status => "crate::packet::status", + State::Login => "crate::packet::login", + State::Game => "crate::packet::game", + } + } +} + impl Display for State { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let name = match self { @@ -108,6 +120,19 @@ pub enum DataType { RefType { ref_name: String, }, + Chat, +} + +impl DataType { + pub fn import<'a>(&self, state: &'a State) -> Option<&'a str> { + match self { + DataType::Uuid { .. } => Some("uuid::Uuid"), + DataType::CompoundTag => Some("nbt::CompoundTag"), + DataType::RefType { .. } => Some(state.data_import()), + DataType::Chat => Some("crate::chat::Message"), + _ => None, + } + } } pub struct Protocol { @@ -129,21 +154,12 @@ impl Protocol { } } - pub fn contains_field_with_type(&self, data_type: DataType) -> bool { - self.server_bound_packets - .iter() - .chain(self.client_bound_packets.iter()) - .flat_map(|p| p.fields.iter()) - .find(|f| f.data_type == data_type) - .is_some() - } - - pub fn contains_field_with_predicate bool>(&self, fun: F) -> bool { + pub fn data_type_imports(&self) -> HashSet<&str> { self.server_bound_packets .iter() .chain(self.client_bound_packets.iter()) .flat_map(|p| p.fields.iter()) - .find(|f| fun(*f)) - .is_some() + .filter_map(|f| f.data_type.import(&self.state)) + .collect() } } diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 1634df7..0106c14 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -123,16 +123,7 @@ pub fn generate_rust_file( "minecraft_protocol_derive::Packet", ]; - if protocol.contains_field_with_predicate(|f| match f.data_type { - DataType::Uuid { .. } => true, - _ => false, - }) { - imports.push("uuid::Uuid") - } - - if protocol.contains_field_with_type(DataType::CompoundTag) { - imports.push("nbt::CompoundTag") - } + imports.extend(protocol.data_type_imports().iter()); template_engine.render_to_write( "protocol_imports", diff --git a/protocol/src/chat.rs b/protocol/src/data/chat.rs similarity index 90% rename from protocol/src/chat.rs rename to protocol/src/data/chat.rs index 8ad49c6..4d9c37e 100644 --- a/protocol/src/chat.rs +++ b/protocol/src/data/chat.rs @@ -6,7 +6,7 @@ //! ## Serialize //! //! ``` -//! use minecraft_protocol::chat::{Payload, Color, MessageBuilder}; +//! use minecraft_protocol::data::chat::{Payload, Color, MessageBuilder}; //! //! let message = MessageBuilder::builder(Payload::text("Hello")) //! .color(Color::Yellow) @@ -25,7 +25,7 @@ //! ## Deserialize //! //! ``` -//! use minecraft_protocol::chat::{MessageBuilder, Color, Payload, Message}; +//! use minecraft_protocol::data::chat::{MessageBuilder, Color, Payload, Message}; //! //! let json = r#" //! { @@ -93,7 +93,7 @@ pub enum Color { /// # Examples /// /// ``` - /// use minecraft_protocol::chat::Color; + /// use minecraft_protocol::data::chat::Color; /// /// let color = Color::Hex("#f98aff".into()); /// ``` @@ -444,7 +444,7 @@ fn test_serialize_text_hello_world() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/text_hello_world.json") + include_str!("../../test/chat/text_hello_world.json") ); } @@ -463,7 +463,7 @@ fn test_deserialize_text_hello_world() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/text_hello_world.json")).unwrap() + Message::from_json(include_str!("../../test/chat/text_hello_world.json")).unwrap() ); } @@ -474,7 +474,7 @@ fn test_serialize_translate_opped_steve() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/translate_opped_steve.json") + include_str!("../../test/chat/translate_opped_steve.json") ); } @@ -485,7 +485,7 @@ fn test_deserialize_translate_opped_steve() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/translate_opped_steve.json")).unwrap() + Message::from_json(include_str!("../../test/chat/translate_opped_steve.json")).unwrap() ); } @@ -503,7 +503,7 @@ fn test_serialize_keybind_jump() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/keybind_jump.json") + include_str!("../../test/chat/keybind_jump.json") ); } @@ -521,7 +521,7 @@ fn test_deserialize_keybind_jump() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/keybind_jump.json")).unwrap() + Message::from_json(include_str!("../../test/chat/keybind_jump.json")).unwrap() ); } @@ -535,7 +535,7 @@ fn test_serialize_click_open_url() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/click_open_url.json") + include_str!("../../test/chat/click_open_url.json") ); } @@ -549,7 +549,7 @@ fn test_deserialize_click_open_url() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/click_open_url.json")).unwrap() + Message::from_json(include_str!("../../test/chat/click_open_url.json")).unwrap() ); } @@ -563,7 +563,7 @@ fn test_serialize_click_run_command() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/click_run_command.json") + include_str!("../../test/chat/click_run_command.json") ); } @@ -577,7 +577,7 @@ fn test_deserialize_click_run_command() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/click_run_command.json")).unwrap() + Message::from_json(include_str!("../../test/chat/click_run_command.json")).unwrap() ); } @@ -591,7 +591,7 @@ fn test_serialize_click_suggest_command() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/click_suggest_command.json") + include_str!("../../test/chat/click_suggest_command.json") ); } @@ -605,7 +605,7 @@ fn test_deserialize_click_suggest_command() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/click_suggest_command.json")).unwrap() + Message::from_json(include_str!("../../test/chat/click_suggest_command.json")).unwrap() ); } @@ -619,7 +619,7 @@ fn test_serialize_click_change_page() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/click_change_page.json") + include_str!("../../test/chat/click_change_page.json") ); } @@ -633,7 +633,7 @@ fn test_deserialize_click_change_page() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/click_change_page.json")).unwrap() + Message::from_json(include_str!("../../test/chat/click_change_page.json")).unwrap() ); } @@ -647,7 +647,7 @@ fn test_serialize_hover_show_text() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/hover_show_text.json") + include_str!("../../test/chat/hover_show_text.json") ); } @@ -661,7 +661,7 @@ fn test_deserialize_hover_show_text() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/hover_show_text.json")).unwrap() + Message::from_json(include_str!("../../test/chat/hover_show_text.json")).unwrap() ); } @@ -675,7 +675,7 @@ fn test_serialize_hover_show_item() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/hover_show_item.json") + include_str!("../../test/chat/hover_show_item.json") ); } @@ -689,7 +689,7 @@ fn test_deserialize_hover_show_item() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/hover_show_item.json")).unwrap() + Message::from_json(include_str!("../../test/chat/hover_show_item.json")).unwrap() ); } @@ -703,7 +703,7 @@ fn test_serialize_hover_show_entity() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/hover_show_entity.json") + include_str!("../../test/chat/hover_show_entity.json") ); } @@ -717,7 +717,7 @@ fn test_deserialize_hover_show_entity() { assert_eq!( expected_message, - Message::from_json(include_str!("../test/chat/hover_show_entity.json")).unwrap() + Message::from_json(include_str!("../../test/chat/hover_show_entity.json")).unwrap() ); } @@ -729,7 +729,7 @@ fn test_serialize_hex_color() { assert_eq!( message.to_json().unwrap(), - include_str!("../test/chat/hex_color.json") + include_str!("../../test/chat/hex_color.json") ); } @@ -740,7 +740,7 @@ fn test_deserialize_hex_color() { .build(); assert_eq!( - Message::from_json(include_str!("../test/chat/hex_color.json")).unwrap(), + Message::from_json(include_str!("../../test/chat/hex_color.json")).unwrap(), expected_message ); } diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs new file mode 100644 index 0000000..3df1fb7 --- /dev/null +++ b/protocol/src/data/game.rs @@ -0,0 +1,22 @@ +use crate::impl_enum_encoder_decoder; +use num_derive::{FromPrimitive, ToPrimitive}; + +#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] +pub enum MessagePosition { + Chat, + System, + HotBar, +} + +impl_enum_encoder_decoder!(MessagePosition); + +#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] +pub enum GameMode { + Survival = 0, + Creative = 1, + Adventure = 2, + Spectator = 3, + Hardcore = 8, +} + +impl_enum_encoder_decoder!(GameMode); diff --git a/protocol/src/data/mod.rs b/protocol/src/data/mod.rs new file mode 100644 index 0000000..02b3360 --- /dev/null +++ b/protocol/src/data/mod.rs @@ -0,0 +1,3 @@ +pub mod chat; +pub mod game; +pub mod status; diff --git a/protocol/src/data/status.rs b/protocol/src/data/status.rs new file mode 100644 index 0000000..a1e73c0 --- /dev/null +++ b/protocol/src/data/status.rs @@ -0,0 +1,32 @@ +use crate::data::chat::Message; +use crate::impl_json_encoder_decoder; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +#[derive(Serialize, Deserialize, Debug)] +pub struct ServerVersion { + pub name: String, + pub protocol: u32, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +pub struct OnlinePlayer { + pub name: String, + pub id: Uuid, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct OnlinePlayers { + pub max: u32, + pub online: u32, + pub sample: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ServerStatus { + pub version: ServerVersion, + pub players: OnlinePlayers, + pub description: Message, +} + +impl_json_encoder_decoder!(ServerStatus); diff --git a/protocol/src/error.rs b/protocol/src/error.rs new file mode 100644 index 0000000..c6240a2 --- /dev/null +++ b/protocol/src/error.rs @@ -0,0 +1,106 @@ +use nbt::decode::TagDecodeError; +use serde_json::error::Error as JsonError; +use std::io::Error as IoError; +use std::string::FromUtf8Error; +use uuid::parser::ParseError as UuidParseError; + +/// Possible errors while encoding packet. +#[derive(Debug)] +pub enum EncodeError { + /// String length can't be more than provided value. + StringTooLong { + /// String length. + length: usize, + /// Max string length. + max_length: u16, + }, + IOError { + io_error: IoError, + }, + JsonError { + json_error: JsonError, + }, +} + +impl From for EncodeError { + fn from(io_error: IoError) -> Self { + EncodeError::IOError { io_error } + } +} + +impl From for EncodeError { + fn from(json_error: JsonError) -> Self { + EncodeError::JsonError { json_error } + } +} + +/// Possible errors while decoding packet. +#[derive(Debug)] +pub enum DecodeError { + /// Packet was not recognized. Invalid data or wrong protocol version. + UnknownPacketType { + type_id: u8, + }, + /// String length can't be more than provided value. + StringTooLong { + /// String length. + length: usize, + /// Max string length. + max_length: u16, + }, + IOError { + io_error: IoError, + }, + JsonError { + json_error: JsonError, + }, + /// Byte array was not recognized as valid UTF-8 string. + Utf8Error { + utf8_error: FromUtf8Error, + }, + /// Boolean are parsed from byte. Valid byte value are 0 or 1. + NonBoolValue, + UuidParseError { + uuid_parse_error: UuidParseError, + }, + // Type id was not parsed as valid enum value. + UnknownEnumType { + type_id: u8, + }, + TagDecodeError { + tag_decode_error: TagDecodeError, + }, + VarIntTooLong { + max_bytes: usize, + }, +} + +impl From for DecodeError { + fn from(io_error: IoError) -> Self { + DecodeError::IOError { io_error } + } +} + +impl From for DecodeError { + fn from(json_error: JsonError) -> Self { + DecodeError::JsonError { json_error } + } +} + +impl From for DecodeError { + fn from(utf8_error: FromUtf8Error) -> Self { + DecodeError::Utf8Error { utf8_error } + } +} + +impl From for DecodeError { + fn from(uuid_parse_error: UuidParseError) -> Self { + DecodeError::UuidParseError { uuid_parse_error } + } +} + +impl From for DecodeError { + fn from(tag_decode_error: TagDecodeError) -> Self { + DecodeError::TagDecodeError { tag_decode_error } + } +} diff --git a/protocol/src/game.rs b/protocol/src/game.rs deleted file mode 100644 index e5d32ca..0000000 --- a/protocol/src/game.rs +++ /dev/null @@ -1,504 +0,0 @@ -use num_derive::{FromPrimitive, ToPrimitive}; - -use crate::chat::Message; -use crate::impl_enum_encoder_decoder; -use crate::DecodeError; -use crate::Decoder; -use minecraft_protocol_derive::Packet; -use nbt::CompoundTag; -use std::io::Read; - -pub enum GameServerBoundPacket { - ServerBoundChatMessage(ServerBoundChatMessage), - ServerBoundKeepAlive(ServerBoundKeepAlive), -} - -pub enum GameClientBoundPacket { - ClientBoundChatMessage(ClientBoundChatMessage), - JoinGame(JoinGame), - ClientBoundKeepAlive(ClientBoundKeepAlive), - ChunkData(ChunkData), - GameDisconnect(GameDisconnect), -} - -impl GameServerBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03, - GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x03 => { - let chat_message = ServerBoundChatMessage::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message)) - } - 0x0F => { - let keep_alive = ServerBoundKeepAlive::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundKeepAlive(keep_alive)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -impl GameClientBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E, - GameClientBoundPacket::GameDisconnect(_) => 0x1A, - GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20, - GameClientBoundPacket::ChunkData(_) => 0x21, - GameClientBoundPacket::JoinGame(_) => 0x25, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x0E => { - let chat_message = ClientBoundChatMessage::decode(reader)?; - - Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message)) - } - 0x1A => { - let game_disconnect = GameDisconnect::decode(reader)?; - - Ok(GameClientBoundPacket::GameDisconnect(game_disconnect)) - } - 0x20 => { - let keep_alive = ClientBoundKeepAlive::decode(reader)?; - - Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive)) - } - 0x21 => { - let chunk_data = ChunkData::decode(reader)?; - - Ok(GameClientBoundPacket::ChunkData(chunk_data)) - } - 0x25 => { - let join_game = JoinGame::decode(reader)?; - - Ok(GameClientBoundPacket::JoinGame(join_game)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -#[derive(Packet, Debug)] -pub struct ServerBoundChatMessage { - #[packet(max_length = 256)] - pub message: String, -} - -impl ServerBoundChatMessage { - pub fn new(message: String) -> GameServerBoundPacket { - let chat_message = ServerBoundChatMessage { message }; - - GameServerBoundPacket::ServerBoundChatMessage(chat_message) - } -} - -#[derive(Packet, Debug)] -pub struct ClientBoundChatMessage { - pub message: Message, - pub position: MessagePosition, -} - -#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] -pub enum MessagePosition { - Chat, - System, - HotBar, -} - -impl_enum_encoder_decoder!(MessagePosition); - -impl ClientBoundChatMessage { - pub fn new(message: Message, position: MessagePosition) -> GameClientBoundPacket { - let chat_message = ClientBoundChatMessage { message, position }; - - GameClientBoundPacket::ClientBoundChatMessage(chat_message) - } -} - -#[derive(Packet, Debug)] -pub struct JoinGame { - pub entity_id: u32, - pub game_mode: GameMode, - pub dimension: i32, - pub max_players: u8, - #[packet(max_length = 16)] - pub level_type: String, - #[packet(with = "var_int")] - pub view_distance: i32, - pub reduced_debug_info: bool, -} - -#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] -pub enum GameMode { - Survival = 0, - Creative = 1, - Adventure = 2, - Spectator = 3, - Hardcore = 8, -} - -impl_enum_encoder_decoder!(GameMode); - -impl JoinGame { - pub fn new( - entity_id: u32, - game_mode: GameMode, - dimension: i32, - max_players: u8, - level_type: String, - view_distance: i32, - reduced_debug_info: bool, - ) -> GameClientBoundPacket { - let join_game = JoinGame { - entity_id, - game_mode, - dimension, - max_players, - level_type, - view_distance, - reduced_debug_info, - }; - - GameClientBoundPacket::JoinGame(join_game) - } -} - -#[derive(Packet)] -pub struct ServerBoundKeepAlive { - pub id: u64, -} - -impl ServerBoundKeepAlive { - pub fn new(id: u64) -> GameServerBoundPacket { - let keep_alive = ServerBoundKeepAlive { id }; - - GameServerBoundPacket::ServerBoundKeepAlive(keep_alive) - } -} - -#[derive(Packet)] -pub struct ClientBoundKeepAlive { - pub id: u64, -} - -impl ClientBoundKeepAlive { - pub fn new(id: u64) -> GameClientBoundPacket { - let keep_alive = ClientBoundKeepAlive { id }; - - GameClientBoundPacket::ClientBoundKeepAlive(keep_alive) - } -} - -#[derive(Packet, Debug)] -pub struct ChunkData { - pub x: i32, - pub z: i32, - pub full: bool, - #[packet(with = "var_int")] - pub primary_mask: i32, - pub heights: CompoundTag, - pub data: Vec, - pub tiles: Vec, -} - -impl ChunkData { - pub fn new( - x: i32, - z: i32, - full: bool, - primary_mask: i32, - heights: CompoundTag, - data: Vec, - tiles: Vec, - ) -> GameClientBoundPacket { - let chunk_data = ChunkData { - x, - z, - full, - primary_mask, - heights, - data, - tiles, - }; - - GameClientBoundPacket::ChunkData(chunk_data) - } -} - -#[derive(Packet, Debug)] -pub struct GameDisconnect { - pub reason: Message, -} - -impl GameDisconnect { - pub fn new(reason: Message) -> GameClientBoundPacket { - let game_disconnect = GameDisconnect { reason }; - - GameClientBoundPacket::GameDisconnect(game_disconnect) - } -} - -#[cfg(test)] -mod tests { - use crate::chat::{Message, Payload}; - use crate::game::{ - ChunkData, ClientBoundChatMessage, ClientBoundKeepAlive, GameDisconnect, GameMode, - JoinGame, MessagePosition, ServerBoundChatMessage, ServerBoundKeepAlive, - }; - use crate::{DecodeError, Encoder, EncoderWriteExt, STRING_MAX_LENGTH}; - use crate::{Decoder, EncodeError}; - use nbt::CompoundTag; - use std::io::Cursor; - - #[test] - fn test_server_bound_chat_message_encode() { - let chat_message = ServerBoundChatMessage { - message: String::from("hello server!"), - }; - - let mut vec = Vec::new(); - chat_message.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/server_bound_chat_message.dat").to_vec() - ); - } - - #[test] - fn test_server_bound_chat_message_decode() { - let mut cursor = Cursor::new( - include_bytes!("../test/packet/game/server_bound_chat_message.dat").to_vec(), - ); - let chat_message = ServerBoundChatMessage::decode(&mut cursor).unwrap(); - - assert_eq!(chat_message.message, "hello server!"); - } - - #[test] - fn test_server_bound_chat_message_encode_invalid_length() { - let chat_message = ServerBoundChatMessage { - message: "abc".repeat(100), - }; - - let mut vec = Vec::new(); - - let encode_error = chat_message - .encode(&mut vec) - .err() - .expect("Expected error `StringTooLong` because message has invalid length"); - - match encode_error { - EncodeError::StringTooLong { length, max_length } => { - assert_eq!(length, 300); - assert_eq!(max_length, 256); - } - _ => panic!("Expected `StringTooLong` but got `{:?}`", encode_error), - } - } - - #[test] - fn test_server_bound_chat_message_decode_invalid_length() { - let message = "abc".repeat(100); - - let mut vec = Vec::new(); - vec.write_string(&message, STRING_MAX_LENGTH).unwrap(); - - let mut cursor = Cursor::new(vec); - - let decode_error = ServerBoundChatMessage::decode(&mut cursor) - .err() - .expect("Expected error `StringTooLong` because message has invalid length"); - - match decode_error { - DecodeError::StringTooLong { length, max_length } => { - assert_eq!(length, 300); - assert_eq!(max_length, 256); - } - _ => panic!("Expected `StringTooLong` but got `{:?}`", decode_error), - } - } - - #[test] - fn test_client_bound_chat_message_encode() { - let chat_message = ClientBoundChatMessage { - message: Message::new(Payload::text("hello client!")), - position: MessagePosition::System, - }; - - let mut vec = Vec::new(); - chat_message.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/client_bound_chat_message.dat").to_vec() - ); - } - - #[test] - fn test_client_bound_chat_message_decode() { - let mut cursor = Cursor::new( - include_bytes!("../test/packet/game/client_bound_chat_message.dat").to_vec(), - ); - let chat_message = ClientBoundChatMessage::decode(&mut cursor).unwrap(); - - assert_eq!( - chat_message.message, - Message::new(Payload::text("hello client!")) - ); - - assert_eq!(chat_message.position, MessagePosition::System); - } - - #[test] - fn test_server_bound_keep_alive_encode() { - let keep_alive = ServerBoundKeepAlive { id: 31122019 }; - - let mut vec = Vec::new(); - keep_alive.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/server_bound_keep_alive.dat").to_vec() - ); - } - - #[test] - fn test_server_bound_keep_alive_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/game/server_bound_keep_alive.dat").to_vec()); - let keep_alive = ServerBoundKeepAlive::decode(&mut cursor).unwrap(); - - assert_eq!(keep_alive.id, 31122019); - } - - #[test] - fn test_client_bound_keep_alive_encode() { - let keep_alive = ClientBoundKeepAlive { id: 240714 }; - - let mut vec = Vec::new(); - keep_alive.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/client_bound_keep_alive.dat").to_vec() - ); - } - - #[test] - fn test_client_bound_keep_alive_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/game/client_bound_keep_alive.dat").to_vec()); - let keep_alive = ClientBoundKeepAlive::decode(&mut cursor).unwrap(); - - assert_eq!(keep_alive.id, 240714); - } - - #[test] - fn test_join_game_encode() { - let join_game = JoinGame { - entity_id: 27, - game_mode: GameMode::Spectator, - dimension: 23, - max_players: 100, - level_type: String::from("default"), - view_distance: 10, - reduced_debug_info: true, - }; - - let mut vec = Vec::new(); - join_game.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/join_game.dat").to_vec() - ); - } - - #[test] - fn test_join_game_decode() { - let mut cursor = Cursor::new(include_bytes!("../test/packet/game/join_game.dat").to_vec()); - let join_game = JoinGame::decode(&mut cursor).unwrap(); - - assert_eq!(join_game.entity_id, 27); - assert_eq!(join_game.game_mode, GameMode::Spectator); - assert_eq!(join_game.dimension, 23); - assert_eq!(join_game.max_players, 100); - assert_eq!(join_game.level_type, String::from("default")); - assert_eq!(join_game.view_distance, 10); - assert!(join_game.reduced_debug_info); - } - - #[test] - fn test_chunk_data_encode() { - let chunk_data = ChunkData { - x: -2, - z: 5, - full: true, - primary_mask: 65535, - heights: CompoundTag::named("HeightMaps"), - data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - tiles: vec![CompoundTag::named("TileEntity")], - }; - - let mut vec = Vec::new(); - chunk_data.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/chunk_data.dat").to_vec() - ); - } - - #[test] - fn test_chunk_data_decode() { - let mut cursor = Cursor::new(include_bytes!("../test/packet/game/chunk_data.dat").to_vec()); - let chunk_data = ChunkData::decode(&mut cursor).unwrap(); - - assert_eq!(chunk_data.x, -2); - assert_eq!(chunk_data.z, 5); - assert!(chunk_data.full); - assert_eq!(chunk_data.heights.name, Some(String::from("HeightMaps"))); - assert_eq!(chunk_data.data, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - assert_eq!(chunk_data.primary_mask, 65535); - assert_eq!(chunk_data.tiles[0].name, Some(String::from("TileEntity"))); - } - - #[test] - fn test_game_disconnect_encode() { - let game_disconnect = GameDisconnect { - reason: Message::new(Payload::text("Message")), - }; - - let mut vec = Vec::new(); - game_disconnect.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/game/game_disconnect.dat").to_vec() - ); - } - - #[test] - fn test_game_disconnect_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/game/game_disconnect.dat").to_vec()); - let game_disconnect = GameDisconnect::decode(&mut cursor).unwrap(); - - assert_eq!( - game_disconnect.reason, - Message::new(Payload::text("Message")) - ); - } -} diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index fa0aa78..5ed10cf 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,25 +1,20 @@ //! This crate implements Minecraft protocol. //! //! Information about protocol can be found at https://wiki.vg/Protocol. -use io::Error as IoError; -use std::io; -use std::io::{Cursor, Read, Write}; -use std::string::FromUtf8Error; +use std::io::{Read, Write}; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use serde_json::error::Error as JsonError; -use uuid::parser::ParseError as UuidParseError; - -use crate::chat::Message; -use nbt::decode::TagDecodeError; use nbt::CompoundTag; use num_traits::{FromPrimitive, ToPrimitive}; use uuid::Uuid; -pub mod chat; -pub mod game; -pub mod login; -pub mod status; +use data::chat::Message; + +use crate::error::{DecodeError, EncodeError}; + +pub mod data; +pub mod error; +pub mod packet; /// Current supported protocol version. pub const PROTOCOL_VERSION: u32 = 498; @@ -27,107 +22,6 @@ pub const PROTOCOL_VERSION: u32 = 498; const STRING_MAX_LENGTH: u16 = 32_768; const HYPHENATED_UUID_LENGTH: u16 = 36; -/// Possible errors while encoding packet. -#[derive(Debug)] -pub enum EncodeError { - /// String length can't be more than provided value. - StringTooLong { - /// String length. - length: usize, - /// Max string length. - max_length: u16, - }, - IOError { - io_error: IoError, - }, - JsonError { - json_error: JsonError, - }, -} - -impl From for EncodeError { - fn from(io_error: IoError) -> Self { - EncodeError::IOError { io_error } - } -} - -impl From for EncodeError { - fn from(json_error: JsonError) -> Self { - EncodeError::JsonError { json_error } - } -} - -/// Possible errors while decoding packet. -#[derive(Debug)] -pub enum DecodeError { - /// Packet was not recognized. Invalid data or wrong protocol version. - UnknownPacketType { - type_id: u8, - }, - /// String length can't be more than provided value. - StringTooLong { - /// String length. - length: usize, - /// Max string length. - max_length: u16, - }, - IOError { - io_error: IoError, - }, - JsonError { - json_error: JsonError, - }, - /// Byte array was not recognized as valid UTF-8 string. - Utf8Error { - utf8_error: FromUtf8Error, - }, - /// Boolean are parsed from byte. Valid byte value are 0 or 1. - NonBoolValue, - UuidParseError { - uuid_parse_error: UuidParseError, - }, - // Type id was not parsed as valid enum value. - UnknownEnumType { - type_id: u8, - }, - TagDecodeError { - tag_decode_error: TagDecodeError, - }, - VarIntTooLong { - max_bytes: usize, - }, -} - -impl From for DecodeError { - fn from(io_error: IoError) -> Self { - DecodeError::IOError { io_error } - } -} - -impl From for DecodeError { - fn from(json_error: JsonError) -> Self { - DecodeError::JsonError { json_error } - } -} - -impl From for DecodeError { - fn from(utf8_error: FromUtf8Error) -> Self { - DecodeError::Utf8Error { utf8_error } - } -} - -impl From for DecodeError { - fn from(uuid_parse_error: UuidParseError) -> Self { - DecodeError::UuidParseError { uuid_parse_error } - } -} - -impl From for DecodeError { - fn from(tag_decode_error: TagDecodeError) -> Self { - DecodeError::TagDecodeError { tag_decode_error } - } -} - trait Encoder { fn encode(&self, writer: &mut W) -> Result<(), EncodeError>; } @@ -546,9 +440,10 @@ macro_rules! impl_json_encoder_decoder ( ); mod var_int { + use std::io::{Read, Write}; + use crate::{DecodeError, EncodeError}; use crate::{DecoderReadExt, EncoderWriteExt}; - use std::io::{Read, Write}; pub fn encode(value: &i32, writer: &mut W) -> Result<(), EncodeError> { writer.write_var_i32(*value)?; @@ -562,9 +457,10 @@ mod var_int { } mod var_long { + use std::io::{Read, Write}; + use crate::{DecodeError, EncodeError}; use crate::{DecoderReadExt, EncoderWriteExt}; - use std::io::{Read, Write}; pub fn encode(value: &i64, writer: &mut W) -> Result<(), EncodeError> { writer.write_var_i64(*value)?; @@ -578,9 +474,10 @@ mod var_long { } mod rest { - use crate::{DecodeError, EncodeError}; use std::io::{Read, Write}; + use crate::{DecodeError, EncodeError}; + pub fn encode(value: &[u8], writer: &mut W) -> Result<(), EncodeError> { writer.write_all(value)?; @@ -596,11 +493,13 @@ mod rest { } mod uuid_hyp_str { + use std::io::{Read, Write}; + + use uuid::Uuid; + use crate::{ DecodeError, DecoderReadExt, EncodeError, EncoderWriteExt, HYPHENATED_UUID_LENGTH, }; - use std::io::{Read, Write}; - use uuid::Uuid; pub fn encode(value: &Uuid, writer: &mut W) -> Result<(), EncodeError> { let uuid_hyphenated_string = value.to_hyphenated().to_string(); diff --git a/protocol/src/login.rs b/protocol/src/login.rs deleted file mode 100644 index d18331e..0000000 --- a/protocol/src/login.rs +++ /dev/null @@ -1,479 +0,0 @@ -use crate::chat::Message; -use crate::DecodeError; -use crate::Decoder; -use std::io::Read; -use uuid::Uuid; - -use minecraft_protocol_derive::Packet; - -pub enum LoginServerBoundPacket { - LoginStart(LoginStart), - EncryptionResponse(EncryptionResponse), - LoginPluginResponse(LoginPluginResponse), -} - -pub enum LoginClientBoundPacket { - LoginDisconnect(LoginDisconnect), - EncryptionRequest(EncryptionRequest), - LoginSuccess(LoginSuccess), - SetCompression(SetCompression), - LoginPluginRequest(LoginPluginRequest), -} - -impl LoginServerBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - LoginServerBoundPacket::LoginStart(_) => 0x00, - LoginServerBoundPacket::EncryptionResponse(_) => 0x01, - LoginServerBoundPacket::LoginPluginResponse(_) => 0x02, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x00 => { - let login_start = LoginStart::decode(reader)?; - - Ok(LoginServerBoundPacket::LoginStart(login_start)) - } - 0x01 => { - let encryption_response = EncryptionResponse::decode(reader)?; - - Ok(LoginServerBoundPacket::EncryptionResponse( - encryption_response, - )) - } - 0x02 => { - let login_plugin_response = LoginPluginResponse::decode(reader)?; - - Ok(LoginServerBoundPacket::LoginPluginResponse( - login_plugin_response, - )) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -impl LoginClientBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - LoginClientBoundPacket::LoginDisconnect(_) => 0x00, - LoginClientBoundPacket::EncryptionRequest(_) => 0x01, - LoginClientBoundPacket::LoginSuccess(_) => 0x02, - LoginClientBoundPacket::SetCompression(_) => 0x03, - LoginClientBoundPacket::LoginPluginRequest(_) => 0x04, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x00 => { - let login_disconnect = LoginDisconnect::decode(reader)?; - - Ok(LoginClientBoundPacket::LoginDisconnect(login_disconnect)) - } - 0x01 => { - let encryption_request = EncryptionRequest::decode(reader)?; - - Ok(LoginClientBoundPacket::EncryptionRequest( - encryption_request, - )) - } - 0x02 => { - let login_success = LoginSuccess::decode(reader)?; - - Ok(LoginClientBoundPacket::LoginSuccess(login_success)) - } - 0x03 => { - let set_compression = SetCompression::decode(reader)?; - - Ok(LoginClientBoundPacket::SetCompression(set_compression)) - } - 0x04 => { - let login_plugin_request = LoginPluginRequest::decode(reader)?; - - Ok(LoginClientBoundPacket::LoginPluginRequest( - login_plugin_request, - )) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -#[derive(Packet, Debug)] -pub struct LoginStart { - pub name: String, -} - -impl LoginStart { - pub fn new(name: String) -> LoginServerBoundPacket { - let login_start = LoginStart { name }; - - LoginServerBoundPacket::LoginStart(login_start) - } -} - -#[derive(Packet, Debug)] -pub struct EncryptionResponse { - pub shared_secret: Vec, - pub verify_token: Vec, -} - -impl EncryptionResponse { - pub fn new(shared_secret: Vec, verify_token: Vec) -> LoginServerBoundPacket { - let encryption_response = EncryptionResponse { - shared_secret, - verify_token, - }; - - LoginServerBoundPacket::EncryptionResponse(encryption_response) - } -} - -#[derive(Packet, Debug)] -pub struct LoginPluginResponse { - #[packet(with = "var_int")] - pub message_id: i32, - pub successful: bool, - #[packet(with = "rest")] - pub data: Vec, -} - -impl LoginPluginResponse { - pub fn new(message_id: i32, successful: bool, data: Vec) -> LoginServerBoundPacket { - let login_plugin_response = LoginPluginResponse { - message_id, - successful, - data, - }; - - LoginServerBoundPacket::LoginPluginResponse(login_plugin_response) - } -} - -#[derive(Packet, Debug)] -pub struct LoginDisconnect { - pub reason: Message, -} - -impl LoginDisconnect { - pub fn new(reason: Message) -> LoginClientBoundPacket { - let login_disconnect = LoginDisconnect { reason }; - - LoginClientBoundPacket::LoginDisconnect(login_disconnect) - } -} - -#[derive(Packet, Debug)] -pub struct EncryptionRequest { - #[packet(max_length = 20)] - pub server_id: String, - pub public_key: Vec, - pub verify_token: Vec, -} - -impl EncryptionRequest { - pub fn new( - server_id: String, - public_key: Vec, - verify_token: Vec, - ) -> LoginClientBoundPacket { - let encryption_request = EncryptionRequest { - server_id, - public_key, - verify_token, - }; - - LoginClientBoundPacket::EncryptionRequest(encryption_request) - } -} - -#[derive(Packet, Debug)] -pub struct LoginSuccess { - #[packet(with = "uuid_hyp_str")] - pub uuid: Uuid, - #[packet(max_length = 16)] - pub username: String, -} - -impl LoginSuccess { - pub fn new(uuid: Uuid, username: String) -> LoginClientBoundPacket { - let login_success = LoginSuccess { uuid, username }; - - LoginClientBoundPacket::LoginSuccess(login_success) - } -} - -#[derive(Packet, Debug)] -pub struct SetCompression { - #[packet(with = "var_int")] - pub threshold: i32, -} - -impl SetCompression { - pub fn new(threshold: i32) -> LoginClientBoundPacket { - let set_compression = SetCompression { threshold }; - - LoginClientBoundPacket::SetCompression(set_compression) - } -} - -#[derive(Packet, Debug)] -pub struct LoginPluginRequest { - #[packet(with = "var_int")] - pub message_id: i32, - pub channel: String, - #[packet(with = "rest")] - pub data: Vec, -} - -impl LoginPluginRequest { - pub fn new(message_id: i32, channel: String, data: Vec) -> LoginClientBoundPacket { - let login_plugin_request = LoginPluginRequest { - message_id, - channel, - data, - }; - - LoginClientBoundPacket::LoginPluginRequest(login_plugin_request) - } -} - -#[cfg(test)] -mod tests { - use crate::chat::{Message, Payload}; - use crate::login::{EncryptionRequest, LoginDisconnect, LoginPluginRequest, SetCompression}; - use crate::login::{EncryptionResponse, LoginPluginResponse}; - use crate::login::{LoginStart, LoginSuccess}; - use crate::Decoder; - use crate::Encoder; - use std::io::Cursor; - use uuid::Uuid; - - #[test] - fn test_login_start_packet_encode() { - let login_start = LoginStart { - name: String::from("Username"), - }; - - let mut vec = Vec::new(); - login_start.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_start.dat").to_vec() - ); - } - - #[test] - fn test_login_start_packet_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_start.dat").to_vec()); - let login_start = LoginStart::decode(&mut cursor).unwrap(); - - assert_eq!(login_start.name, String::from("Username")); - } - - #[test] - fn test_encryption_response_encode() { - let encryption_response = EncryptionResponse { - shared_secret: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - verify_token: vec![1, 2, 3, 4], - }; - - let mut vec = Vec::new(); - encryption_response.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/encryption_response.dat").to_vec() - ); - } - - #[test] - fn test_encryption_response_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/encryption_response.dat").to_vec()); - let encryption_response = EncryptionResponse::decode(&mut cursor).unwrap(); - - assert_eq!( - encryption_response.shared_secret, - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ); - assert_eq!(encryption_response.verify_token, vec![1, 2, 3, 4]); - } - - #[test] - fn test_login_plugin_response_encode() { - let login_plugin_response = LoginPluginResponse { - message_id: 55, - successful: true, - data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - }; - - let mut vec = Vec::new(); - login_plugin_response.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_plugin_response.dat").to_vec() - ); - } - - #[test] - fn test_login_plugin_response_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_plugin_response.dat").to_vec()); - let login_plugin_response = LoginPluginResponse::decode(&mut cursor).unwrap(); - - assert_eq!(login_plugin_response.message_id, 55); - assert!(login_plugin_response.successful); - assert_eq!( - login_plugin_response.data, - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ); - } - - #[test] - fn test_login_disconnect_encode() { - let login_disconnect = LoginDisconnect { - reason: Message::new(Payload::text("Message")), - }; - - let mut vec = Vec::new(); - login_disconnect.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_disconnect.dat").to_vec() - ); - } - - #[test] - fn test_login_disconnect_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_disconnect.dat").to_vec()); - let login_disconnect = LoginDisconnect::decode(&mut cursor).unwrap(); - - assert_eq!( - login_disconnect.reason, - Message::new(Payload::text("Message")) - ); - } - - #[test] - fn test_encryption_request_encode() { - let encryption_request = EncryptionRequest { - server_id: String::from("ServerID"), - public_key: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - verify_token: vec![1, 2, 3, 4], - }; - - let mut vec = Vec::new(); - encryption_request.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/encryption_request.dat").to_vec() - ); - } - - #[test] - fn test_encryption_request_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/encryption_request.dat").to_vec()); - let encryption_request = EncryptionRequest::decode(&mut cursor).unwrap(); - - assert_eq!(encryption_request.server_id, String::from("ServerID")); - assert_eq!( - encryption_request.public_key, - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ); - assert_eq!(encryption_request.verify_token, vec![1, 2, 3, 4]); - } - - #[test] - fn test_login_success_encode() { - let login_success = LoginSuccess { - uuid: Uuid::parse_str("35ee313b-d89a-41b8-b25e-d32e8aff0389").unwrap(), - username: String::from("Username"), - }; - - let mut vec = Vec::new(); - login_success.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_success.dat").to_vec() - ); - } - - #[test] - fn test_login_success_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_success.dat").to_vec()); - let login_success = LoginSuccess::decode(&mut cursor).unwrap(); - - assert_eq!(login_success.username, String::from("Username")); - - assert_eq!( - login_success.uuid, - Uuid::parse_str("35ee313b-d89a-41b8-b25e-d32e8aff0389").unwrap() - ); - } - - #[test] - fn test_set_compression_encode() { - let set_compression = SetCompression { threshold: 1 }; - - let mut vec = Vec::new(); - set_compression.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_set_compression.dat").to_vec() - ); - } - - #[test] - fn test_set_compression_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_set_compression.dat").to_vec()); - let set_compression = SetCompression::decode(&mut cursor).unwrap(); - - assert_eq!(set_compression.threshold, 1); - } - - #[test] - fn test_login_plugin_request_encode() { - let login_plugin_request = LoginPluginRequest { - message_id: 55, - channel: String::from("Channel"), - data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - }; - - let mut vec = Vec::new(); - login_plugin_request.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/login/login_plugin_request.dat").to_vec() - ); - } - - #[test] - fn test_login_plugin_request_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/login/login_plugin_request.dat").to_vec()); - let login_plugin_request = LoginPluginRequest::decode(&mut cursor).unwrap(); - - assert_eq!(login_plugin_request.message_id, 55); - assert_eq!(login_plugin_request.channel, String::from("Channel")); - assert_eq!( - login_plugin_request.data, - vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ); - } -} diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs new file mode 100644 index 0000000..bb8e585 --- /dev/null +++ b/protocol/src/packet/game.rs @@ -0,0 +1,140 @@ +use crate::data::chat::Message; +use crate::data::game::{GameMode, MessagePosition}; +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use nbt::CompoundTag; +use std::io::Read; + +pub enum GameServerBoundPacket { + ServerBoundChatMessage(ServerBoundChatMessage), + ServerBoundKeepAlive(ServerBoundKeepAlive), +} + +pub enum GameClientBoundPacket { + ClientBoundChatMessage(ClientBoundChatMessage), + JoinGame(JoinGame), + ClientBoundKeepAlive(ClientBoundKeepAlive), + ChunkData(ChunkData), + GameDisconnect(GameDisconnect), +} + +impl GameServerBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03, + GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x03 => { + let chat_message = ServerBoundChatMessage::decode(reader)?; + + Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message)) + } + 0x0F => { + let keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(GameServerBoundPacket::ServerBoundKeepAlive(keep_alive)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } +} + +impl GameClientBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E, + GameClientBoundPacket::GameDisconnect(_) => 0x1A, + GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20, + GameClientBoundPacket::ChunkData(_) => 0x21, + GameClientBoundPacket::JoinGame(_) => 0x25, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x0E => { + let chat_message = ClientBoundChatMessage::decode(reader)?; + + Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message)) + } + 0x1A => { + let game_disconnect = GameDisconnect::decode(reader)?; + + Ok(GameClientBoundPacket::GameDisconnect(game_disconnect)) + } + 0x20 => { + let keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive)) + } + 0x21 => { + let chunk_data = ChunkData::decode(reader)?; + + Ok(GameClientBoundPacket::ChunkData(chunk_data)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(GameClientBoundPacket::JoinGame(join_game)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChatMessage { + #[packet(max_length = 256)] + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChatMessage { + pub message: Message, + pub position: MessagePosition, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: u32, + pub game_mode: GameMode, + pub dimension: i32, + pub max_players: u8, + #[packet(max_length = 16)] + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, +} + +#[derive(Packet)] +pub struct ServerBoundKeepAlive { + pub id: u64, +} + +#[derive(Packet)] +pub struct ClientBoundKeepAlive { + pub id: u64, +} + +#[derive(Packet, Debug)] +pub struct ChunkData { + pub x: i32, + pub z: i32, + pub full: bool, + #[packet(with = "var_int")] + pub primary_mask: i32, + pub heights: CompoundTag, + pub data: Vec, + pub tiles: Vec, +} + +#[derive(Packet, Debug)] +pub struct GameDisconnect { + pub reason: Message, +} diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs new file mode 100644 index 0000000..c70f8e4 --- /dev/null +++ b/protocol/src/packet/login.rs @@ -0,0 +1,159 @@ +use crate::data::chat::Message; +use crate::DecodeError; +use crate::Decoder; +use std::io::Read; +use uuid::Uuid; + +use minecraft_protocol_derive::Packet; + +pub enum LoginServerBoundPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +pub enum LoginClientBoundPacket { + LoginDisconnect(LoginDisconnect), + EncryptionRequest(EncryptionRequest), + LoginSuccess(LoginSuccess), + SetCompression(SetCompression), + LoginPluginRequest(LoginPluginRequest), +} + +impl LoginServerBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + LoginServerBoundPacket::LoginStart(_) => 0x00, + LoginServerBoundPacket::EncryptionResponse(_) => 0x01, + LoginServerBoundPacket::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(LoginServerBoundPacket::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(LoginServerBoundPacket::EncryptionResponse( + encryption_response, + )) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(LoginServerBoundPacket::LoginPluginResponse( + login_plugin_response, + )) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } +} + +impl LoginClientBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + LoginClientBoundPacket::LoginDisconnect(_) => 0x00, + LoginClientBoundPacket::EncryptionRequest(_) => 0x01, + LoginClientBoundPacket::LoginSuccess(_) => 0x02, + LoginClientBoundPacket::SetCompression(_) => 0x03, + LoginClientBoundPacket::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_disconnect = LoginDisconnect::decode(reader)?; + + Ok(LoginClientBoundPacket::LoginDisconnect(login_disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(LoginClientBoundPacket::EncryptionRequest( + encryption_request, + )) + } + 0x02 => { + let login_success = LoginSuccess::decode(reader)?; + + Ok(LoginClientBoundPacket::LoginSuccess(login_success)) + } + 0x03 => { + let set_compression = SetCompression::decode(reader)?; + + Ok(LoginClientBoundPacket::SetCompression(set_compression)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(LoginClientBoundPacket::LoginPluginRequest( + login_plugin_request, + )) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + pub successful: bool, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginDisconnect { + pub reason: Message, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + #[packet(max_length = 20)] + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginSuccess { + #[packet(with = "uuid_hyp_str")] + pub uuid: Uuid, + #[packet(max_length = 16)] + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct SetCompression { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/packet/mod.rs b/protocol/src/packet/mod.rs new file mode 100644 index 0000000..986f00e --- /dev/null +++ b/protocol/src/packet/mod.rs @@ -0,0 +1,3 @@ +pub mod game; +pub mod login; +pub mod status; diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs new file mode 100644 index 0000000..a801f2f --- /dev/null +++ b/protocol/src/packet/status.rs @@ -0,0 +1,60 @@ +use crate::data::status::ServerStatus; +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum StatusServerBoundPacket { + StatusRequest, + PingRequest(PingRequest), +} + +pub enum StatusClientBoundPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl StatusServerBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + StatusServerBoundPacket::StatusRequest => 0x00, + StatusServerBoundPacket::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(StatusServerBoundPacket::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(StatusServerBoundPacket::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } +} + +impl StatusClientBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + StatusClientBoundPacket::StatusResponse(_) => 0x00, + StatusClientBoundPacket::PingResponse(_) => 0x01, + } + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: u64, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: u64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub server_status: ServerStatus, +} diff --git a/protocol/src/status.rs b/protocol/src/status.rs deleted file mode 100644 index 1d8f195..0000000 --- a/protocol/src/status.rs +++ /dev/null @@ -1,235 +0,0 @@ -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -use crate::chat::Message; -use crate::impl_json_encoder_decoder; -use crate::DecodeError; -use crate::Decoder; -use minecraft_protocol_derive::Packet; -use std::io::Read; - -pub enum StatusServerBoundPacket { - StatusRequest, - PingRequest(PingRequest), -} - -pub enum StatusClientBoundPacket { - StatusResponse(StatusResponse), - PingResponse(PingResponse), -} - -impl StatusServerBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - StatusServerBoundPacket::StatusRequest => 0x00, - StatusServerBoundPacket::PingRequest(_) => 0x01, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x00 => Ok(StatusServerBoundPacket::StatusRequest), - 0x01 => { - let ping_request = PingRequest::decode(reader)?; - - Ok(StatusServerBoundPacket::PingRequest(ping_request)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -impl StatusClientBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - StatusClientBoundPacket::StatusResponse(_) => 0x00, - StatusClientBoundPacket::PingResponse(_) => 0x01, - } - } -} - -#[derive(Packet, Debug)] -pub struct PingRequest { - pub time: u64, -} - -impl PingRequest { - pub fn new(time: u64) -> StatusServerBoundPacket { - let ping_request = PingRequest { time }; - - StatusServerBoundPacket::PingRequest(ping_request) - } -} - -#[derive(Packet, Debug)] -pub struct PingResponse { - pub time: u64, -} - -impl PingResponse { - pub fn new(time: u64) -> StatusClientBoundPacket { - let ping_response = PingResponse { time }; - - StatusClientBoundPacket::PingResponse(ping_response) - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ServerStatus { - pub version: ServerVersion, - pub players: OnlinePlayers, - pub description: Message, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ServerVersion { - pub name: String, - pub protocol: u32, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct OnlinePlayers { - pub max: u32, - pub online: u32, - pub sample: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] -pub struct OnlinePlayer { - pub name: String, - pub id: Uuid, -} - -#[derive(Packet, Debug)] -pub struct StatusResponse { - pub server_status: ServerStatus, -} - -impl_json_encoder_decoder!(ServerStatus); - -impl StatusResponse { - pub fn new(server_status: ServerStatus) -> StatusClientBoundPacket { - let status_response = StatusResponse { server_status }; - - StatusClientBoundPacket::StatusResponse(status_response) - } -} - -#[cfg(test)] -mod tests { - use crate::chat::{Message, Payload}; - use crate::status::{ - OnlinePlayer, OnlinePlayers, PingRequest, PingResponse, ServerStatus, ServerVersion, - StatusResponse, - }; - use crate::Decoder; - use crate::Encoder; - use std::io::Cursor; - use uuid::Uuid; - - #[test] - fn test_ping_request_encode() { - let ping_request = PingRequest { - time: 1577735845610, - }; - - let mut vec = Vec::new(); - ping_request.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/status/ping_request.dat").to_vec() - ); - } - - #[test] - fn test_status_ping_request_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/status/ping_request.dat").to_vec()); - let ping_request = PingRequest::decode(&mut cursor).unwrap(); - - assert_eq!(ping_request.time, 1577735845610); - } - - #[test] - fn test_ping_response_encode() { - let ping_response = PingResponse { - time: 1577735845610, - }; - - let mut vec = Vec::new(); - ping_response.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/status/ping_response.dat").to_vec() - ); - } - - #[test] - fn test_status_ping_response_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/status/ping_response.dat").to_vec()); - let ping_response = PingResponse::decode(&mut cursor).unwrap(); - - assert_eq!(ping_response.time, 1577735845610); - } - - #[test] - fn test_status_response_encode() { - let version = ServerVersion { - name: String::from("1.15.1"), - protocol: 575, - }; - - let player = OnlinePlayer { - id: Uuid::parse_str("2a1e1912-7103-4add-80fc-91ebc346cbce").unwrap(), - name: String::from("Username"), - }; - - let players = OnlinePlayers { - online: 10, - max: 100, - sample: vec![player], - }; - - let server_status = ServerStatus { - version, - description: Message::new(Payload::text("Description")), - players, - }; - - let status_response = StatusResponse { server_status }; - - let mut vec = Vec::new(); - status_response.encode(&mut vec).unwrap(); - - assert_eq!( - vec, - include_bytes!("../test/packet/status/status_response.dat").to_vec() - ); - } - - #[test] - fn test_status_response_decode() { - let mut cursor = - Cursor::new(include_bytes!("../test/packet/status/status_response.dat").to_vec()); - let status_response = StatusResponse::decode(&mut cursor).unwrap(); - let server_status = status_response.server_status; - - let player = OnlinePlayer { - id: Uuid::parse_str("2a1e1912-7103-4add-80fc-91ebc346cbce").unwrap(), - name: String::from("Username"), - }; - - assert_eq!(server_status.version.name, String::from("1.15.1")); - assert_eq!(server_status.version.protocol, 575); - assert_eq!(server_status.players.max, 100); - assert_eq!(server_status.players.online, 10); - assert_eq!(server_status.players.sample, vec![player]); - assert_eq!( - server_status.description, - Message::new(Payload::text("Description")) - ); - } -} diff --git a/protocol/test/packet/game/chunk_data.dat b/protocol/test/packet/game/chunk_data.dat deleted file mode 100644 index fb01ab1b9962f49fe3de11bed7d4775cef59ba74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmezW|NlP*1_oBf|Noh}7`QxAGt)Cld=m?b8Mqjkm|0la*f}`47=bb&nK`Mhc_o=8 Gl?(vDj1FP| diff --git a/protocol/test/packet/game/client_bound_chat_message.dat b/protocol/test/packet/game/client_bound_chat_message.dat deleted file mode 100644 index f66ac04..0000000 --- a/protocol/test/packet/game/client_bound_chat_message.dat +++ /dev/null @@ -1 +0,0 @@ -{"text":"hello client!"} \ No newline at end of file diff --git a/protocol/test/packet/game/client_bound_keep_alive.dat b/protocol/test/packet/game/client_bound_keep_alive.dat deleted file mode 100644 index 51d9e4cb88bdeba56ec28ea7b2da446bf6fa714b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8 NcmZQz00QPUUH}2J0Qvv` diff --git a/protocol/test/packet/game/game_disconnect.dat b/protocol/test/packet/game/game_disconnect.dat deleted file mode 100644 index 104c7f9..0000000 --- a/protocol/test/packet/game/game_disconnect.dat +++ /dev/null @@ -1 +0,0 @@ -{"text":"Message"} \ No newline at end of file diff --git a/protocol/test/packet/game/join_game.dat b/protocol/test/packet/game/join_game.dat deleted file mode 100644 index e2e43830bbbc50042243e09ddbe8d36d11c7ac27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20 bcmZQzV31~JU| Date: Sun, 24 Jan 2021 02:11:26 +0300 Subject: [PATCH 05/22] Fix tests and rename to packet templates --- protocol-generator/src/main.rs | 28 +++++++++---------- .../{protocol_enum.hbs => packet_enum.hbs} | 0 ...rotocol_imports.hbs => packet_imports.hbs} | 0 ...rotocol_structs.hbs => packet_structs.hbs} | 0 protocol/src/lib.rs | 3 +- 5 files changed, 16 insertions(+), 15 deletions(-) rename protocol-generator/templates/{protocol_enum.hbs => packet_enum.hbs} (100%) rename protocol-generator/templates/{protocol_imports.hbs => packet_imports.hbs} (100%) rename protocol-generator/templates/{protocol_structs.hbs => packet_structs.hbs} (100%) diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 0106c14..5fa6f51 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -17,22 +17,22 @@ pub fn main() { template_engine .register_template_file( - "protocol_imports", - "protocol-generator/templates/protocol_imports.hbs", + "packet_imports", + "protocol-generator/templates/packet_imports.hbs", ) .expect("Failed to register template"); template_engine .register_template_file( - "protocol_enum", - "protocol-generator/templates/protocol_enum.hbs", + "packet_enum", + "protocol-generator/templates/packet_enum.hbs", ) .expect("Failed to register template"); template_engine .register_template_file( - "protocol_structs", - "protocol-generator/templates/protocol_structs.hbs", + "packet_structs", + "protocol-generator/templates/packet_structs.hbs", ) .expect("Failed to register template"); @@ -97,7 +97,7 @@ pub fn main() { #[derive(Serialize)] struct GenerateContext<'a> { - protocol_enum_name: String, + packet_enum_name: String, packets: &'a Vec, } @@ -107,12 +107,12 @@ pub fn generate_rust_file( mut writer: W, ) -> Result<(), TemplateRenderError> { let server_bound_ctx = GenerateContext { - protocol_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Server), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Server), packets: &protocol.server_bound_packets, }; let client_bound_ctx = GenerateContext { - protocol_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Client), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Client), packets: &protocol.client_bound_packets, }; @@ -126,16 +126,16 @@ pub fn generate_rust_file( imports.extend(protocol.data_type_imports().iter()); template_engine.render_to_write( - "protocol_imports", + "packet_imports", &json!({ "imports": imports }), &mut writer, )?; - template_engine.render_to_write("protocol_enum", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("protocol_enum", &client_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?; - template_engine.render_to_write("protocol_structs", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("protocol_structs", &client_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?; Ok(()) } diff --git a/protocol-generator/templates/protocol_enum.hbs b/protocol-generator/templates/packet_enum.hbs similarity index 100% rename from protocol-generator/templates/protocol_enum.hbs rename to protocol-generator/templates/packet_enum.hbs diff --git a/protocol-generator/templates/protocol_imports.hbs b/protocol-generator/templates/packet_imports.hbs similarity index 100% rename from protocol-generator/templates/protocol_imports.hbs rename to protocol-generator/templates/packet_imports.hbs diff --git a/protocol-generator/templates/protocol_structs.hbs b/protocol-generator/templates/packet_structs.hbs similarity index 100% rename from protocol-generator/templates/protocol_structs.hbs rename to protocol-generator/templates/packet_structs.hbs diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 5ed10cf..6c92a9c 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,7 +1,7 @@ //! This crate implements Minecraft protocol. //! //! Information about protocol can be found at https://wiki.vg/Protocol. -use std::io::{Read, Write}; +use std::io::{Cursor, Read, Write}; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use nbt::CompoundTag; @@ -493,6 +493,7 @@ mod rest { } mod uuid_hyp_str { + use std::io::Cursor; use std::io::{Read, Write}; use uuid::Uuid; From 3189f0c0d9d1671923bc43285f020c9d55d5b06f Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 31 Jan 2021 22:46:50 +0300 Subject: [PATCH 06/22] Add minecraft-data as git submodule --- .gitmodules | 3 +++ protocol-generator/minecraft-data | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 protocol-generator/minecraft-data diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3e029d7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "protocol-generator/minecraft-data"] + path = protocol-generator/minecraft-data + url = https://github.com/PrismarineJS/minecraft-data diff --git a/protocol-generator/minecraft-data b/protocol-generator/minecraft-data new file mode 160000 index 0000000..e656aaf --- /dev/null +++ b/protocol-generator/minecraft-data @@ -0,0 +1 @@ +Subproject commit e656aafb77f477d3726ed46209f0d4bb7052a04b From 3229d02418b05dd0292dead59205199eb2694afd Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sat, 6 Feb 2021 18:59:51 +0300 Subject: [PATCH 07/22] WIP input parse --- protocol-generator/Cargo.toml | 2 +- protocol-generator/src/data/input.rs | 138 ++++++++++++++++++ protocol-generator/src/data/mod.rs | 2 + .../src/{data.rs => data/output.rs} | 0 protocol-generator/src/main.rs | 93 +++++------- 5 files changed, 174 insertions(+), 61 deletions(-) create mode 100644 protocol-generator/src/data/input.rs create mode 100644 protocol-generator/src/data/mod.rs rename protocol-generator/src/{data.rs => data/output.rs} (100%) diff --git a/protocol-generator/Cargo.toml b/protocol-generator/Cargo.toml index a4fd963..b8c85ae 100644 --- a/protocol-generator/Cargo.toml +++ b/protocol-generator/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/eihwaz/minecraft-protocol" keywords = ["minecraft", "cli", "protocol", "packet", "io"] [dependencies] -clap = "2.33.3" +structopt = "0.3" serde = "1.0.120" serde_json = "1.0" handlebars = "3.5.2" diff --git a/protocol-generator/src/data/input.rs b/protocol-generator/src/data/input.rs new file mode 100644 index 0000000..bd6b091 --- /dev/null +++ b/protocol-generator/src/data/input.rs @@ -0,0 +1,138 @@ +use serde::Deserialize; +use serde::Serialize; +use std::collections::HashMap; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Protocol { + handshaking: ProtocolState, + status: ProtocolState, + login: ProtocolState, + #[serde(rename = "play")] + game: ProtocolState, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ProtocolState { + to_client: ProtocolTypes, + to_server: ProtocolTypes, +} + +#[derive(Debug, Serialize, Deserialize)] +struct ProtocolTypes { + types: HashMap>, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] +enum Container { + Type(String), + Data(Vec), +} + +#[derive(Debug, Serialize, Deserialize)] +struct ContainerData { + name: String, + #[serde(rename = "type")] + container_type: ContainerDataType, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] +enum ContainerDataType { + Type(String), + Mapper(String, Mappings), + Switch(String, Switch), +} + +#[derive(Debug, Serialize, Deserialize)] +struct Mappings { + #[serde(rename = "type")] + mappings_type: String, + mappings: HashMap, +} + +#[derive(Debug, Serialize, Deserialize)] +struct Switch { + #[serde(rename = "compareTo")] + compare_to: String, + fields: HashMap, +} + +#[cfg(test)] +mod tests { + use crate::data::input::*; + use std::collections::HashMap; + + #[test] + fn test_to_json() { + let mut types = HashMap::new(); + + let data = vec![ + ContainerData { + name: "protocolVersion".to_string(), + container_type: ContainerDataType::Type("varint".to_string()), + }, + ContainerData { + name: "serverHost".to_string(), + container_type: ContainerDataType::Type("string".to_string()), + }, + ContainerData { + name: "serverPort".to_string(), + container_type: ContainerDataType::Type("u16".to_string()), + }, + ContainerData { + name: "nextState".to_string(), + container_type: ContainerDataType::Type("varint".to_string()), + }, + ]; + + types.insert( + "packet_set_protocol".to_owned(), + vec![ + Container::Type("container".to_owned()), + Container::Data(data), + ], + ); + + let mut mappings = HashMap::new(); + mappings.insert("0x00".to_owned(), "set_protocol".to_owned()); + mappings.insert("0xfe".to_owned(), "legacy_server_list_ping".to_owned()); + + let data2 = vec![ContainerData { + name: "name".to_string(), + container_type: ContainerDataType::Mapper( + "mapper".to_owned(), + Mappings { + mappings_type: "varint".to_string(), + mappings, + }, + ), + }]; + + // _type: ContainerDataType::Mapper(vec![ + // Mapper::Type("mapper".to_owned()), + // Mapper::Data("varint".to_owned(), mappings), + // ]), + + types.insert( + "packet".to_owned(), + vec![ + Container::Type("container".to_owned()), + Container::Data(data2), + ], + ); + + // let protocol = Protocol { + // handshaking: ProtocolState { + // to_server: ProtocolTypes { types }, + // }, + // }; + // + // let j = serde_json::to_string(&protocol).unwrap(); + // + // println!("{}", j); + // + // assert_eq!("", j); + } +} diff --git a/protocol-generator/src/data/mod.rs b/protocol-generator/src/data/mod.rs new file mode 100644 index 0000000..7d1a548 --- /dev/null +++ b/protocol-generator/src/data/mod.rs @@ -0,0 +1,2 @@ +pub mod input; +pub mod output; diff --git a/protocol-generator/src/data.rs b/protocol-generator/src/data/output.rs similarity index 100% rename from protocol-generator/src/data.rs rename to protocol-generator/src/data/output.rs diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 5fa6f51..187011d 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -1,14 +1,43 @@ mod data; -use crate::data::*; +use crate::data::input; use handlebars::*; use heck::SnakeCase; + +use crate::data::output; +use crate::data::output::Bound; use serde::Serialize; use serde_json::json; use std::fs::File; use std::io::Write; +use structopt::StructOpt; + +#[derive(StructOpt)] +#[structopt(name = "protocol-generator")] +struct Opt { + #[structopt(short, long, default_value = "1.14.4")] + protocol_version: String, +} pub fn main() { + let opt: Opt = Opt::from_args(); + let template_engine = create_template_engine(); + + let protocol_data_file_name = format!( + "protocol-generator/minecraft-data/data/pc/{}/protocol.json", + opt.protocol_version + ); + + let protocol_data_file = + File::open(protocol_data_file_name).expect("Failed to open protocol data file"); + + let protocol_data: input::Protocol = + serde_json::from_reader(protocol_data_file).expect("Failed to parse protocol data"); + + println!("{:#?}", protocol_data) +} + +fn create_template_engine() -> Handlebars<'static> { let mut template_engine = Handlebars::new(); template_engine.register_helper("snake_case", Box::new(format_snake_case)); @@ -36,73 +65,17 @@ pub fn main() { ) .expect("Failed to register template"); - let protocol = Protocol::new( - State::Login, - vec![ - Packet::new( - "LoginStart", - vec![Field::new("name", DataType::String { max_length: 256 })], - ), - Packet::new( - "EncryptionResponse", - vec![ - Field::new("shared_secret", DataType::ByteArray { rest: true }), - Field::new("verify_token", DataType::ByteArray { rest: true }), - ], - ), - Packet::new( - "LoginPluginResponse", - vec![ - Field::new("message_id", DataType::Int { var_int: true }), - Field::new("successful", DataType::Boolean), - Field::new("data", DataType::ByteArray { rest: true }), - ], - ), - ], - vec![ - Packet::new( - "LoginDisconnect", - vec![ - Field::new("hyphenated", DataType::Uuid { hyphenated: true }), - Field::new("default", DataType::Uuid { hyphenated: false }), - ], - ), - Packet::new( - "EncryptionRequest", - vec![Field::new( - "game_mode", - DataType::RefType { - ref_name: "GameMode".to_string(), - }, - )], - ), - Packet::new( - "LoginSuccess", - vec![Field::new( - "server_status", - DataType::RefType { - ref_name: "ServerStatus".to_string(), - }, - )], - ), - Packet::new("SetCompression", vec![]), - Packet::new("LoginPluginRequest", vec![]), - ], - ); - - let file = File::create("login.rs").expect("Failed to create file"); - - generate_rust_file(&protocol, &template_engine, &file).expect("Failed to generate rust file"); + template_engine } #[derive(Serialize)] struct GenerateContext<'a> { packet_enum_name: String, - packets: &'a Vec, + packets: &'a Vec, } pub fn generate_rust_file( - protocol: &Protocol, + protocol: &output::Protocol, template_engine: &Handlebars, mut writer: W, ) -> Result<(), TemplateRenderError> { From ab4d40e48235d6eece7b4f86bc39b2b511ea0959 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sat, 6 Feb 2021 23:18:39 +0300 Subject: [PATCH 08/22] Rework input json parser --- protocol-generator/src/data/input.rs | 179 +++++++++++---------------- 1 file changed, 71 insertions(+), 108 deletions(-) diff --git a/protocol-generator/src/data/input.rs b/protocol-generator/src/data/input.rs index bd6b091..5918a30 100644 --- a/protocol-generator/src/data/input.rs +++ b/protocol-generator/src/data/input.rs @@ -2,7 +2,7 @@ use serde::Deserialize; use serde::Serialize; use std::collections::HashMap; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] pub struct Protocol { handshaking: ProtocolState, status: ProtocolState, @@ -11,128 +11,91 @@ pub struct Protocol { game: ProtocolState, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ProtocolState { - to_client: ProtocolTypes, - to_server: ProtocolTypes, + to_client: ProtocolData, + to_server: ProtocolData, } -#[derive(Debug, Serialize, Deserialize)] -struct ProtocolTypes { - types: HashMap>, +#[derive(Debug, Deserialize)] +struct ProtocolData { + types: HashMap>, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] #[serde(untagged)] -enum Container { +enum Data { Type(String), - Data(Vec), + Container(Vec), + Mapper { + #[serde(rename = "type")] + mappings_type: String, + mappings: HashMap, + }, + Switch(Switch), + List(Box), + Bitfield(Vec), } -#[derive(Debug, Serialize, Deserialize)] -struct ContainerData { - name: String, - #[serde(rename = "type")] - container_type: ContainerDataType, -} - -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] #[serde(untagged)] -enum ContainerDataType { - Type(String), - Mapper(String, Mappings), - Switch(String, Switch), +enum Container { + Value { + name: String, + #[serde(rename = "type")] + data: Data, + }, + Array { + name: Option, + #[serde(rename = "type")] + data: Vec, + }, } -#[derive(Debug, Serialize, Deserialize)] -struct Mappings { - #[serde(rename = "type")] - mappings_type: String, - mappings: HashMap, +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum Switch { + Empty { + #[serde(rename = "compareTo")] + compare_to: String, + }, + Value { + #[serde(rename = "compareTo")] + compare_to: String, + fields: HashMap, + }, + List { + #[serde(rename = "compareTo")] + compare_to: String, + fields: HashMap>, + }, } -#[derive(Debug, Serialize, Deserialize)] -struct Switch { - #[serde(rename = "compareTo")] - compare_to: String, - fields: HashMap, +#[derive(Debug, Deserialize)] +#[serde(untagged)] +enum List { + Empty { + #[serde(rename = "countType")] + count_type: String, + }, + Value { + #[serde(rename = "countType")] + count_type: String, + #[serde(rename = "type")] + list_type: Data, + }, + Array { + #[serde(rename = "countType")] + count_type: String, + #[serde(rename = "type")] + list_type: Vec, + }, } -#[cfg(test)] -mod tests { - use crate::data::input::*; - use std::collections::HashMap; - - #[test] - fn test_to_json() { - let mut types = HashMap::new(); - - let data = vec![ - ContainerData { - name: "protocolVersion".to_string(), - container_type: ContainerDataType::Type("varint".to_string()), - }, - ContainerData { - name: "serverHost".to_string(), - container_type: ContainerDataType::Type("string".to_string()), - }, - ContainerData { - name: "serverPort".to_string(), - container_type: ContainerDataType::Type("u16".to_string()), - }, - ContainerData { - name: "nextState".to_string(), - container_type: ContainerDataType::Type("varint".to_string()), - }, - ]; - - types.insert( - "packet_set_protocol".to_owned(), - vec![ - Container::Type("container".to_owned()), - Container::Data(data), - ], - ); - - let mut mappings = HashMap::new(); - mappings.insert("0x00".to_owned(), "set_protocol".to_owned()); - mappings.insert("0xfe".to_owned(), "legacy_server_list_ping".to_owned()); - - let data2 = vec![ContainerData { - name: "name".to_string(), - container_type: ContainerDataType::Mapper( - "mapper".to_owned(), - Mappings { - mappings_type: "varint".to_string(), - mappings, - }, - ), - }]; - - // _type: ContainerDataType::Mapper(vec![ - // Mapper::Type("mapper".to_owned()), - // Mapper::Data("varint".to_owned(), mappings), - // ]), - - types.insert( - "packet".to_owned(), - vec![ - Container::Type("container".to_owned()), - Container::Data(data2), - ], - ); - - // let protocol = Protocol { - // handshaking: ProtocolState { - // to_server: ProtocolTypes { types }, - // }, - // }; - // - // let j = serde_json::to_string(&protocol).unwrap(); - // - // println!("{}", j); - // - // assert_eq!("", j); - } +#[derive(Debug, Deserialize)] +struct BitField { + name: String, + size: usize, + signed: bool, } From d589bd795657a4a43b64018f599c50289316ddf6 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 02:20:12 +0300 Subject: [PATCH 09/22] Fix packet ids --- protocol-generator/Cargo.toml | 1 + protocol-generator/src/data/input.rs | 37 +++---- protocol-generator/src/data/output.rs | 4 +- protocol-generator/src/main.rs | 106 ++++++++++++++++++- protocol-generator/templates/packet_enum.hbs | 11 +- 5 files changed, 130 insertions(+), 29 deletions(-) diff --git a/protocol-generator/Cargo.toml b/protocol-generator/Cargo.toml index b8c85ae..9b325a4 100644 --- a/protocol-generator/Cargo.toml +++ b/protocol-generator/Cargo.toml @@ -15,3 +15,4 @@ serde = "1.0.120" serde_json = "1.0" handlebars = "3.5.2" heck = "0.3.2" +linked-hash-map = { version = "0.5.4", features = ["serde_impl"] } diff --git a/protocol-generator/src/data/input.rs b/protocol-generator/src/data/input.rs index 5918a30..68ca055 100644 --- a/protocol-generator/src/data/input.rs +++ b/protocol-generator/src/data/input.rs @@ -1,37 +1,38 @@ +use linked_hash_map::LinkedHashMap; use serde::Deserialize; use serde::Serialize; use std::collections::HashMap; #[derive(Debug, Deserialize)] pub struct Protocol { - handshaking: ProtocolState, - status: ProtocolState, - login: ProtocolState, + pub handshaking: ProtocolState, + pub status: ProtocolState, + pub login: ProtocolState, #[serde(rename = "play")] - game: ProtocolState, + pub game: ProtocolState, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ProtocolState { - to_client: ProtocolData, - to_server: ProtocolData, + pub to_client: ProtocolData, + pub to_server: ProtocolData, } #[derive(Debug, Deserialize)] -struct ProtocolData { - types: HashMap>, +pub struct ProtocolData { + pub types: LinkedHashMap>, } #[derive(Debug, Deserialize)] #[serde(untagged)] -enum Data { +pub enum Data { Type(String), Container(Vec), Mapper { #[serde(rename = "type")] mappings_type: String, - mappings: HashMap, + mappings: LinkedHashMap, }, Switch(Switch), List(Box), @@ -40,13 +41,13 @@ enum Data { #[derive(Debug, Deserialize)] #[serde(untagged)] -enum Container { +pub enum Container { Value { name: String, #[serde(rename = "type")] data: Data, }, - Array { + List { name: Option, #[serde(rename = "type")] data: Vec, @@ -55,7 +56,7 @@ enum Container { #[derive(Debug, Deserialize)] #[serde(untagged)] -enum Switch { +pub enum Switch { Empty { #[serde(rename = "compareTo")] compare_to: String, @@ -63,18 +64,18 @@ enum Switch { Value { #[serde(rename = "compareTo")] compare_to: String, - fields: HashMap, + fields: LinkedHashMap, }, List { #[serde(rename = "compareTo")] compare_to: String, - fields: HashMap>, + fields: LinkedHashMap>, }, } #[derive(Debug, Deserialize)] #[serde(untagged)] -enum List { +pub enum List { Empty { #[serde(rename = "countType")] count_type: String, @@ -85,7 +86,7 @@ enum List { #[serde(rename = "type")] list_type: Data, }, - Array { + List { #[serde(rename = "countType")] count_type: String, #[serde(rename = "type")] @@ -94,7 +95,7 @@ enum List { } #[derive(Debug, Deserialize)] -struct BitField { +pub struct BitField { name: String, size: usize, signed: bool, diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/data/output.rs index 0f85027..a5b5680 100644 --- a/protocol-generator/src/data/output.rs +++ b/protocol-generator/src/data/output.rs @@ -52,13 +52,15 @@ impl Display for Bound { #[derive(Serialize)] pub struct Packet { + pub id: u8, pub name: String, pub fields: Vec, } impl Packet { - pub fn new(name: impl ToString, fields: Vec) -> Packet { + pub fn new(id: u8, name: impl ToString, fields: Vec) -> Packet { Packet { + id, name: name.to_string(), fields, } diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 187011d..e1fb3f6 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -2,12 +2,15 @@ mod data; use crate::data::input; use handlebars::*; -use heck::SnakeCase; +use heck::{CamelCase, KebabCase, MixedCase, SnakeCase, TitleCase}; +use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::output; -use crate::data::output::Bound; +use crate::data::output::{Bound, Packet, State}; +use linked_hash_map::LinkedHashMap; use serde::Serialize; use serde_json::json; +use std::collections::HashMap; use std::fs::File; use std::io::Write; use structopt::StructOpt; @@ -31,10 +34,35 @@ pub fn main() { let protocol_data_file = File::open(protocol_data_file_name).expect("Failed to open protocol data file"); - let protocol_data: input::Protocol = + let protocol_input: input::Protocol = serde_json::from_reader(protocol_data_file).expect("Failed to parse protocol data"); - println!("{:#?}", protocol_data) + let protocols = vec![ + ( + transform_protocol_state(State::Handshake, &protocol_input.handshaking), + State::Handshake, + ), + ( + transform_protocol_state(State::Status, &protocol_input.status), + State::Status, + ), + ( + transform_protocol_state(State::Login, &protocol_input.login), + State::Login, + ), + ( + transform_protocol_state(State::Game, &protocol_input.game), + State::Game, + ), + ]; + + for (protocol, state) in protocols { + let file_name = format!("{}.rs", state.to_string().to_lowercase()); + let file = File::create(file_name).expect("Failed to create file"); + + generate_rust_file(&protocol, &template_engine, &file) + .expect("Failed to generate rust file"); + } } fn create_template_engine() -> Handlebars<'static> { @@ -68,13 +96,81 @@ fn create_template_engine() -> Handlebars<'static> { template_engine } +fn transform_protocol_state(state: State, protocol_state: &ProtocolState) -> output::Protocol { + let server_bound_packets = transform_protocol_data(&protocol_state.to_server); + let client_bound_packets = transform_protocol_data(&protocol_state.to_client); + + output::Protocol { + state, + server_bound_packets, + client_bound_packets, + } +} + +fn transform_protocol_data(protocol_data: &ProtocolData) -> Vec { + let mut packets = vec![]; + + let reversed_packet_ids = protocol_data + .types + .get("packet") + .and_then(|d| d.get(1)) + .and_then(|d| match d { + Data::Container(data) => data.get(0), + _ => None, + }) + .and_then(|c| match c { + Container::List { data, .. } => data.get(1), + _ => None, + }) + .and_then(|d| match d { + Data::Mapper { mappings, .. } => Some(mappings), + _ => None, + }) + .expect("Failed to get packet ids"); + + let packet_ids: HashMap = reversed_packet_ids + .into_iter() + .map(|(k, v)| { + ( + v.clone(), + u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), + ) + }) + .collect(); + + for (unformatted_name, data) in protocol_data.types.iter() { + if !unformatted_name.starts_with("packet_") + || unformatted_name == "packet_legacy_server_list_ping" + { + continue; + } + + let no_prefix_name = unformatted_name.trim_start_matches("packet_"); + + let id = *packet_ids + .get(no_prefix_name) + .expect("Failed to get packet id"); + let name = no_prefix_name.to_camel_case(); + + let packet = Packet { + id, + name, + fields: vec![], + }; + + packets.push(packet); + } + + packets +} + #[derive(Serialize)] struct GenerateContext<'a> { packet_enum_name: String, packets: &'a Vec, } -pub fn generate_rust_file( +fn generate_rust_file( protocol: &output::Protocol, template_engine: &Handlebars, mut writer: W, diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/packet_enum.hbs index 7915ecc..5cc3ed9 100644 --- a/protocol-generator/templates/packet_enum.hbs +++ b/protocol-generator/templates/packet_enum.hbs @@ -1,15 +1,15 @@ - -pub enum {{protocol_enum_name}} { +{{~#if packets}} +pub enum {{packet_enum_name}} { {{~#each packets as |p|}} {{p.name}}{{#if p.fields}}({{p.name}}){{/if}}{{#unless @last}},{{/unless}} {{~/each}} } -impl {{protocol_enum_name}} { +impl {{packet_enum_name}} { pub fn get_type_id(&self) -> u8 { match self { {{~#each packets as |p|}} - Self::{{p.name}}{{#if p.fields}}(_){{/if}} => {{packet_id @index}}{{#unless @last}},{{/unless}} + Self::{{p.name}}{{#if p.fields}}(_){{/if}} => {{packet_id p.id}}{{#unless @last}},{{/unless}} {{~/each}} } } @@ -17,7 +17,7 @@ impl {{protocol_enum_name}} { pub fn decode(type_id: u8, reader: &mut R) -> Result { match type_id { {{~#each packets as |p|}} - {{@index}} => { + {{packet_id p.id}} => { {{~#if p.fields}} let {{snake_case p.name}} = {{p.name}}::decode(reader)?; @@ -48,3 +48,4 @@ impl {{protocol_enum_name}} { } {{/each~}} } +{{~/if}} \ No newline at end of file From 03267e33189fa17cc2e03e97e8611e8d21e6b8a2 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 15:52:27 +0300 Subject: [PATCH 10/22] Add fields --- protocol-generator/src/data/input.rs | 14 +-- protocol-generator/src/main.rs | 178 ++++++++++++++++++++------- protocol/src/packet/handshake.rs | 52 ++++++++ protocol/src/packet/login.rs | 173 +++++++++++++++++--------- protocol/src/packet/mod.rs | 1 + protocol/src/packet/status.rs | 88 +++++++++---- 6 files changed, 376 insertions(+), 130 deletions(-) create mode 100644 protocol/src/packet/handshake.rs diff --git a/protocol-generator/src/data/input.rs b/protocol-generator/src/data/input.rs index 68ca055..b7a2c30 100644 --- a/protocol-generator/src/data/input.rs +++ b/protocol-generator/src/data/input.rs @@ -1,7 +1,5 @@ use linked_hash_map::LinkedHashMap; use serde::Deserialize; -use serde::Serialize; -use std::collections::HashMap; #[derive(Debug, Deserialize)] pub struct Protocol { @@ -24,7 +22,7 @@ pub struct ProtocolData { pub types: LinkedHashMap>, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum Data { Type(String), @@ -39,7 +37,7 @@ pub enum Data { Bitfield(Vec), } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum Container { Value { @@ -50,11 +48,11 @@ pub enum Container { List { name: Option, #[serde(rename = "type")] - data: Vec, + data_vec: Vec, }, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum Switch { Empty { @@ -73,7 +71,7 @@ pub enum Switch { }, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum List { Empty { @@ -94,7 +92,7 @@ pub enum List { }, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, PartialEq, Eq)] pub struct BitField { name: String, size: usize, diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index e1fb3f6..c09e7be 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -2,12 +2,10 @@ mod data; use crate::data::input; use handlebars::*; -use heck::{CamelCase, KebabCase, MixedCase, SnakeCase, TitleCase}; +use heck::{CamelCase, SnakeCase}; use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::output; -use crate::data::output::{Bound, Packet, State}; -use linked_hash_map::LinkedHashMap; use serde::Serialize; use serde_json::json; use std::collections::HashMap; @@ -39,25 +37,28 @@ pub fn main() { let protocols = vec![ ( - transform_protocol_state(State::Handshake, &protocol_input.handshaking), - State::Handshake, + transform_protocol_state(output::State::Handshake, &protocol_input.handshaking), + output::State::Handshake, ), ( - transform_protocol_state(State::Status, &protocol_input.status), - State::Status, + transform_protocol_state(output::State::Status, &protocol_input.status), + output::State::Status, ), ( - transform_protocol_state(State::Login, &protocol_input.login), - State::Login, - ), - ( - transform_protocol_state(State::Game, &protocol_input.game), - State::Game, + transform_protocol_state(output::State::Login, &protocol_input.login), + output::State::Login, ), + // ( + // transform_protocol_state(State::Game, &protocol_input.game), + // State::Game, + // ), ]; for (protocol, state) in protocols { - let file_name = format!("{}.rs", state.to_string().to_lowercase()); + let file_name = format!( + "protocol/src/packet/{}.rs", + state.to_string().to_lowercase() + ); let file = File::create(file_name).expect("Failed to create file"); generate_rust_file(&protocol, &template_engine, &file) @@ -96,9 +97,14 @@ fn create_template_engine() -> Handlebars<'static> { template_engine } -fn transform_protocol_state(state: State, protocol_state: &ProtocolState) -> output::Protocol { - let server_bound_packets = transform_protocol_data(&protocol_state.to_server); - let client_bound_packets = transform_protocol_data(&protocol_state.to_client); +fn transform_protocol_state( + state: output::State, + protocol_state: &ProtocolState, +) -> output::Protocol { + let server_bound_packets = + transform_protocol_data(&protocol_state.to_server, output::Bound::Server); + let client_bound_packets = + transform_protocol_data(&protocol_state.to_client, output::Bound::Client); output::Protocol { state, @@ -107,9 +113,61 @@ fn transform_protocol_state(state: State, protocol_state: &ProtocolState) -> out } } -fn transform_protocol_data(protocol_data: &ProtocolData) -> Vec { +fn transform_protocol_data( + protocol_data: &ProtocolData, + bound: output::Bound, +) -> Vec { + let packet_ids = get_packet_ids(protocol_data); let mut packets = vec![]; + for (unformatted_name, data_vec) in protocol_data.types.iter() { + if !unformatted_name.starts_with("packet_") + || unformatted_name == "packet_legacy_server_list_ping" + { + continue; + } + + let no_prefix_name = unformatted_name.trim_start_matches("packet_"); + + let id = *packet_ids + .get(no_prefix_name) + .expect("Failed to get packet id"); + let name = rename_packet(&no_prefix_name.to_camel_case(), &bound); + + let mut fields = vec![]; + + for data in data_vec { + if let Data::Container(container_vec) = data { + for container in container_vec { + match container { + Container::Value { name, data } => { + if let Some(field) = transform_field(name, data) { + fields.push(field); + } + } + Container::List { name, data_vec } => { + if let Some(name) = name { + for data in data_vec { + if let Some(field) = transform_field(name, data) { + fields.push(field); + } + } + } + } + } + } + } + } + + let packet = output::Packet { id, name, fields }; + + packets.push(packet); + } + + packets +} + +fn get_packet_ids(protocol_data: &ProtocolData) -> HashMap { let reversed_packet_ids = protocol_data .types .get("packet") @@ -119,7 +177,7 @@ fn transform_protocol_data(protocol_data: &ProtocolData) -> Vec { _ => None, }) .and_then(|c| match c { - Container::List { data, .. } => data.get(1), + Container::List { data_vec, .. } => data_vec.get(1), _ => None, }) .and_then(|d| match d { @@ -128,7 +186,7 @@ fn transform_protocol_data(protocol_data: &ProtocolData) -> Vec { }) .expect("Failed to get packet ids"); - let packet_ids: HashMap = reversed_packet_ids + reversed_packet_ids .into_iter() .map(|(k, v)| { ( @@ -136,32 +194,66 @@ fn transform_protocol_data(protocol_data: &ProtocolData) -> Vec { u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), ) }) - .collect(); - - for (unformatted_name, data) in protocol_data.types.iter() { - if !unformatted_name.starts_with("packet_") - || unformatted_name == "packet_legacy_server_list_ping" - { - continue; - } - - let no_prefix_name = unformatted_name.trim_start_matches("packet_"); + .collect() +} - let id = *packet_ids - .get(no_prefix_name) - .expect("Failed to get packet id"); - let name = no_prefix_name.to_camel_case(); +fn transform_field(unformatted_field_name: &str, data: &Data) -> Option { + match data { + Data::Type(str_type) => match transform_data_type(str_type) { + Some(data_type) => Some(output::Field { + name: format_field_name(unformatted_field_name), + data_type, + }), + None => None, + }, + _ => None, + } +} - let packet = Packet { - id, - name, - fields: vec![], - }; +fn format_field_name(unformatted_field_name: &str) -> String { + if unformatted_field_name == "Type" { + String::from("type_") + } else { + unformatted_field_name.to_snake_case() + } +} - packets.push(packet); +fn transform_data_type(str_type: &str) -> Option { + match str_type { + "bool" => Some(output::DataType::Boolean), + "i8" => Some(output::DataType::Byte), + "i16" => Some(output::DataType::Short), + "i32" => Some(output::DataType::Int { var_int: false }), + "i64" => Some(output::DataType::Long { var_long: false }), + "u8" => Some(output::DataType::UnsignedByte), + "u16" => Some(output::DataType::UnsignedShort), + "f32" => Some(output::DataType::Float), + "f64" => Some(output::DataType::Double), + "varint" => Some(output::DataType::Int { var_int: true }), + "varlong" => Some(output::DataType::Long { var_long: true }), + "string" => Some(output::DataType::String { max_length: 0 }), + "nbt" | "optionalNbt" => Some(output::DataType::CompoundTag), + "UUID" => Some(output::DataType::Uuid { hyphenated: false }), + "buffer" => Some(output::DataType::ByteArray { rest: false }), + "restBuffer" => Some(output::DataType::ByteArray { rest: true }), + _ => { + println!("{}", str_type); + None + } } +} - packets +fn rename_packet(name: &str, bound: &output::Bound) -> String { + match (name, bound) { + ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", + ("EncryptionBegin", output::Bound::Client) => "EncryptionRequest", + ("PingStart", output::Bound::Server) => "StatusRequest", + ("Ping", output::Bound::Server) => "PingRequest", + ("ServerInfo", output::Bound::Client) => "StatusResponse", + ("Ping", output::Bound::Client) => "PingResponse", + _ => name, + } + .to_owned() } #[derive(Serialize)] @@ -176,12 +268,12 @@ fn generate_rust_file( mut writer: W, ) -> Result<(), TemplateRenderError> { let server_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Server), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, output::Bound::Server), packets: &protocol.server_bound_packets, }; let client_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, Bound::Client), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, output::Bound::Client), packets: &protocol.client_bound_packets, }; diff --git a/protocol/src/packet/handshake.rs b/protocol/src/packet/handshake.rs new file mode 100644 index 0000000..77d3687 --- /dev/null +++ b/protocol/src/packet/handshake.rs @@ -0,0 +1,52 @@ +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum HandshakeServerBoundPacket { + SetProtocol(SetProtocol), +} + +impl HandshakeServerBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs index c70f8e4..00c489e 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/packet/login.rs @@ -1,31 +1,21 @@ -use crate::data::chat::Message; use crate::DecodeError; use crate::Decoder; use std::io::Read; -use uuid::Uuid; - use minecraft_protocol_derive::Packet; + pub enum LoginServerBoundPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), - LoginPluginResponse(LoginPluginResponse), -} - -pub enum LoginClientBoundPacket { - LoginDisconnect(LoginDisconnect), - EncryptionRequest(EncryptionRequest), - LoginSuccess(LoginSuccess), - SetCompression(SetCompression), - LoginPluginRequest(LoginPluginRequest), + LoginPluginResponse(LoginPluginResponse) } impl LoginServerBoundPacket { pub fn get_type_id(&self) -> u8 { match self { - LoginServerBoundPacket::LoginStart(_) => 0x00, - LoginServerBoundPacket::EncryptionResponse(_) => 0x01, - LoginServerBoundPacket::LoginPluginResponse(_) => 0x02, + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02 } } @@ -34,119 +24,185 @@ impl LoginServerBoundPacket { 0x00 => { let login_start = LoginStart::decode(reader)?; - Ok(LoginServerBoundPacket::LoginStart(login_start)) + Ok(Self::LoginStart(login_start)) } 0x01 => { let encryption_response = EncryptionResponse::decode(reader)?; - Ok(LoginServerBoundPacket::EncryptionResponse( - encryption_response, - )) + Ok(Self::EncryptionResponse(encryption_response)) } 0x02 => { let login_plugin_response = LoginPluginResponse::decode(reader)?; - Ok(LoginServerBoundPacket::LoginPluginResponse( - login_plugin_response, - )) + Ok(Self::LoginPluginResponse(login_plugin_response)) } - _ => Err(DecodeError::UnknownPacketType { type_id }), + _ => Err(DecodeError::UnknownPacketType { type_id }) } } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { + username + }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { + message_id, + data + }; + + Self::LoginPluginResponse(login_plugin_response) + } +} +pub enum LoginClientBoundPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest) } impl LoginClientBoundPacket { pub fn get_type_id(&self) -> u8 { match self { - LoginClientBoundPacket::LoginDisconnect(_) => 0x00, - LoginClientBoundPacket::EncryptionRequest(_) => 0x01, - LoginClientBoundPacket::LoginSuccess(_) => 0x02, - LoginClientBoundPacket::SetCompression(_) => 0x03, - LoginClientBoundPacket::LoginPluginRequest(_) => 0x04, + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04 } } pub fn decode(type_id: u8, reader: &mut R) -> Result { match type_id { 0x00 => { - let login_disconnect = LoginDisconnect::decode(reader)?; + let disconnect = Disconnect::decode(reader)?; - Ok(LoginClientBoundPacket::LoginDisconnect(login_disconnect)) + Ok(Self::Disconnect(disconnect)) } 0x01 => { let encryption_request = EncryptionRequest::decode(reader)?; - Ok(LoginClientBoundPacket::EncryptionRequest( - encryption_request, - )) + Ok(Self::EncryptionRequest(encryption_request)) } 0x02 => { - let login_success = LoginSuccess::decode(reader)?; + let success = Success::decode(reader)?; - Ok(LoginClientBoundPacket::LoginSuccess(login_success)) + Ok(Self::Success(success)) } 0x03 => { - let set_compression = SetCompression::decode(reader)?; + let compress = Compress::decode(reader)?; - Ok(LoginClientBoundPacket::SetCompression(set_compression)) + Ok(Self::Compress(compress)) } 0x04 => { let login_plugin_request = LoginPluginRequest::decode(reader)?; - Ok(LoginClientBoundPacket::LoginPluginRequest( - login_plugin_request, - )) + Ok(Self::LoginPluginRequest(login_plugin_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }), + _ => Err(DecodeError::UnknownPacketType { type_id }) } } -} + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { + reason + }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request(server_id: String, public_key: Vec, verify_token: Vec) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { + uuid, + username + }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { + threshold + }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} #[derive(Packet, Debug)] pub struct LoginStart { - pub name: String, + pub username: String } #[derive(Packet, Debug)] pub struct EncryptionResponse { pub shared_secret: Vec, - pub verify_token: Vec, + pub verify_token: Vec } #[derive(Packet, Debug)] pub struct LoginPluginResponse { #[packet(with = "var_int")] pub message_id: i32, - pub successful: bool, #[packet(with = "rest")] - pub data: Vec, + pub data: Vec } + #[derive(Packet, Debug)] -pub struct LoginDisconnect { - pub reason: Message, +pub struct Disconnect { + pub reason: String } #[derive(Packet, Debug)] pub struct EncryptionRequest { - #[packet(max_length = 20)] pub server_id: String, pub public_key: Vec, - pub verify_token: Vec, + pub verify_token: Vec } #[derive(Packet, Debug)] -pub struct LoginSuccess { - #[packet(with = "uuid_hyp_str")] - pub uuid: Uuid, - #[packet(max_length = 16)] - pub username: String, +pub struct Success { + pub uuid: String, + pub username: String } #[derive(Packet, Debug)] -pub struct SetCompression { +pub struct Compress { #[packet(with = "var_int")] - pub threshold: i32, + pub threshold: i32 } #[derive(Packet, Debug)] @@ -155,5 +211,6 @@ pub struct LoginPluginRequest { pub message_id: i32, pub channel: String, #[packet(with = "rest")] - pub data: Vec, + pub data: Vec } + diff --git a/protocol/src/packet/mod.rs b/protocol/src/packet/mod.rs index 986f00e..29a91c1 100644 --- a/protocol/src/packet/mod.rs +++ b/protocol/src/packet/mod.rs @@ -1,3 +1,4 @@ pub mod game; +pub mod handshake; pub mod login; pub mod status; diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs index a801f2f..a754a9c 100644 --- a/protocol/src/packet/status.rs +++ b/protocol/src/packet/status.rs @@ -1,60 +1,106 @@ -use crate::data::status::ServerStatus; use crate::DecodeError; use crate::Decoder; -use minecraft_protocol_derive::Packet; use std::io::Read; +use minecraft_protocol_derive::Packet; + pub enum StatusServerBoundPacket { StatusRequest, - PingRequest(PingRequest), -} - -pub enum StatusClientBoundPacket { - StatusResponse(StatusResponse), - PingResponse(PingResponse), + PingRequest(PingRequest) } impl StatusServerBoundPacket { pub fn get_type_id(&self) -> u8 { match self { - StatusServerBoundPacket::StatusRequest => 0x00, - StatusServerBoundPacket::PingRequest(_) => 0x01, + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01 } } pub fn decode(type_id: u8, reader: &mut R) -> Result { match type_id { - 0x00 => Ok(StatusServerBoundPacket::StatusRequest), + 0x00 => { + Ok(Self::StatusRequest) + } 0x01 => { let ping_request = PingRequest::decode(reader)?; - Ok(StatusServerBoundPacket::PingRequest(ping_request)) + Ok(Self::PingRequest(ping_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }), + _ => Err(DecodeError::UnknownPacketType { type_id }) } } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { + time + }; + + Self::PingRequest(ping_request) + } +} +pub enum StatusClientBoundPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse) } impl StatusClientBoundPacket { pub fn get_type_id(&self) -> u8 { match self { - StatusClientBoundPacket::StatusResponse(_) => 0x00, - StatusClientBoundPacket::PingResponse(_) => 0x01, + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01 } } -} + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }) + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { + response + }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { + time + }; + + Self::PingResponse(ping_response) + } +} #[derive(Packet, Debug)] pub struct PingRequest { - pub time: u64, + pub time: i64 } + #[derive(Packet, Debug)] -pub struct PingResponse { - pub time: u64, +pub struct StatusResponse { + pub response: String } #[derive(Packet, Debug)] -pub struct StatusResponse { - pub server_status: ServerStatus, +pub struct PingResponse { + pub time: i64 } + From 99a331c6abbf1a468118c5da1432b7f579019e41 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 16:09:48 +0300 Subject: [PATCH 11/22] Fix --- generate.sh | 4 ++ protocol-generator/templates/packet_enum.hbs | 2 +- .../templates/packet_imports.hbs | 4 +- protocol/src/lib.rs | 14 ++++ protocol/src/packet/handshake.rs | 3 + protocol/src/packet/login.rs | 71 +++++++++---------- protocol/src/packet/status.rs | 43 +++++------ 7 files changed, 75 insertions(+), 66 deletions(-) create mode 100755 generate.sh diff --git a/generate.sh b/generate.sh new file mode 100755 index 0000000..8a3dd85 --- /dev/null +++ b/generate.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cargo run +cargo fmt diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/packet_enum.hbs index 5cc3ed9..0b81503 100644 --- a/protocol-generator/templates/packet_enum.hbs +++ b/protocol-generator/templates/packet_enum.hbs @@ -48,4 +48,4 @@ impl {{packet_enum_name}} { } {{/each~}} } -{{~/if}} \ No newline at end of file +{{~/if}} diff --git a/protocol-generator/templates/packet_imports.hbs b/protocol-generator/templates/packet_imports.hbs index 03e74a9..a97ad24 100644 --- a/protocol-generator/templates/packet_imports.hbs +++ b/protocol-generator/templates/packet_imports.hbs @@ -1,3 +1,5 @@ +// This file is automatically generated. +// It is not intended for manual editing. {{#each imports as |i|~}} use {{i}}; -{{/each}} +{{/each~}} diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 6c92a9c..e7eee2b 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -239,6 +239,20 @@ impl Decoder for u8 { } } +impl Encoder for u16 { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + Ok(writer.write_u16::(*self)?) + } +} + +impl Decoder for u16 { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + Ok(reader.read_u16::()?) + } +} + impl Encoder for i32 { fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { Ok(writer.write_i32::(*self)?) diff --git a/protocol/src/packet/handshake.rs b/protocol/src/packet/handshake.rs index 77d3687..90d4683 100644 --- a/protocol/src/packet/handshake.rs +++ b/protocol/src/packet/handshake.rs @@ -1,3 +1,5 @@ +// This file is automatically generated. +// It is not intended for manual editing. use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; @@ -41,6 +43,7 @@ impl HandshakeServerBoundPacket { Self::SetProtocol(set_protocol) } } + #[derive(Packet, Debug)] pub struct SetProtocol { #[packet(with = "var_int")] diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs index 00c489e..4414da5 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/packet/login.rs @@ -1,13 +1,14 @@ +// This file is automatically generated. +// It is not intended for manual editing. use crate::DecodeError; use crate::Decoder; -use std::io::Read; use minecraft_protocol_derive::Packet; - +use std::io::Read; pub enum LoginServerBoundPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), - LoginPluginResponse(LoginPluginResponse) + LoginPluginResponse(LoginPluginResponse), } impl LoginServerBoundPacket { @@ -15,7 +16,7 @@ impl LoginServerBoundPacket { match self { Self::LoginStart(_) => 0x00, Self::EncryptionResponse(_) => 0x01, - Self::LoginPluginResponse(_) => 0x02 + Self::LoginPluginResponse(_) => 0x02, } } @@ -36,14 +37,12 @@ impl LoginServerBoundPacket { Ok(Self::LoginPluginResponse(login_plugin_response)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } pub fn login_start(username: String) -> Self { - let login_start = LoginStart { - username - }; + let login_start = LoginStart { username }; Self::LoginStart(login_start) } @@ -51,27 +50,25 @@ impl LoginServerBoundPacket { pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { let encryption_response = EncryptionResponse { shared_secret, - verify_token + verify_token, }; Self::EncryptionResponse(encryption_response) } pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { - let login_plugin_response = LoginPluginResponse { - message_id, - data - }; + let login_plugin_response = LoginPluginResponse { message_id, data }; Self::LoginPluginResponse(login_plugin_response) } } + pub enum LoginClientBoundPacket { Disconnect(Disconnect), EncryptionRequest(EncryptionRequest), Success(Success), Compress(Compress), - LoginPluginRequest(LoginPluginRequest) + LoginPluginRequest(LoginPluginRequest), } impl LoginClientBoundPacket { @@ -81,7 +78,7 @@ impl LoginClientBoundPacket { Self::EncryptionRequest(_) => 0x01, Self::Success(_) => 0x02, Self::Compress(_) => 0x03, - Self::LoginPluginRequest(_) => 0x04 + Self::LoginPluginRequest(_) => 0x04, } } @@ -112,41 +109,38 @@ impl LoginClientBoundPacket { Ok(Self::LoginPluginRequest(login_plugin_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } pub fn disconnect(reason: String) -> Self { - let disconnect = Disconnect { - reason - }; + let disconnect = Disconnect { reason }; Self::Disconnect(disconnect) } - pub fn encryption_request(server_id: String, public_key: Vec, verify_token: Vec) -> Self { + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { let encryption_request = EncryptionRequest { server_id, public_key, - verify_token + verify_token, }; Self::EncryptionRequest(encryption_request) } pub fn success(uuid: String, username: String) -> Self { - let success = Success { - uuid, - username - }; + let success = Success { uuid, username }; Self::Success(success) } pub fn compress(threshold: i32) -> Self { - let compress = Compress { - threshold - }; + let compress = Compress { threshold }; Self::Compress(compress) } @@ -155,21 +149,22 @@ impl LoginClientBoundPacket { let login_plugin_request = LoginPluginRequest { message_id, channel, - data + data, }; Self::LoginPluginRequest(login_plugin_request) } } + #[derive(Packet, Debug)] pub struct LoginStart { - pub username: String + pub username: String, } #[derive(Packet, Debug)] pub struct EncryptionResponse { pub shared_secret: Vec, - pub verify_token: Vec + pub verify_token: Vec, } #[derive(Packet, Debug)] @@ -177,32 +172,31 @@ pub struct LoginPluginResponse { #[packet(with = "var_int")] pub message_id: i32, #[packet(with = "rest")] - pub data: Vec + pub data: Vec, } - #[derive(Packet, Debug)] pub struct Disconnect { - pub reason: String + pub reason: String, } #[derive(Packet, Debug)] pub struct EncryptionRequest { pub server_id: String, pub public_key: Vec, - pub verify_token: Vec + pub verify_token: Vec, } #[derive(Packet, Debug)] pub struct Success { pub uuid: String, - pub username: String + pub username: String, } #[derive(Packet, Debug)] pub struct Compress { #[packet(with = "var_int")] - pub threshold: i32 + pub threshold: i32, } #[derive(Packet, Debug)] @@ -211,6 +205,5 @@ pub struct LoginPluginRequest { pub message_id: i32, pub channel: String, #[packet(with = "rest")] - pub data: Vec + pub data: Vec, } - diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs index a754a9c..4beb5be 100644 --- a/protocol/src/packet/status.rs +++ b/protocol/src/packet/status.rs @@ -1,33 +1,32 @@ +// This file is automatically generated. +// It is not intended for manual editing. use crate::DecodeError; use crate::Decoder; -use std::io::Read; use minecraft_protocol_derive::Packet; - +use std::io::Read; pub enum StatusServerBoundPacket { StatusRequest, - PingRequest(PingRequest) + PingRequest(PingRequest), } impl StatusServerBoundPacket { pub fn get_type_id(&self) -> u8 { match self { Self::StatusRequest => 0x00, - Self::PingRequest(_) => 0x01 + Self::PingRequest(_) => 0x01, } } pub fn decode(type_id: u8, reader: &mut R) -> Result { match type_id { - 0x00 => { - Ok(Self::StatusRequest) - } + 0x00 => Ok(Self::StatusRequest), 0x01 => { let ping_request = PingRequest::decode(reader)?; Ok(Self::PingRequest(ping_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } @@ -36,23 +35,22 @@ impl StatusServerBoundPacket { } pub fn ping_request(time: i64) -> Self { - let ping_request = PingRequest { - time - }; + let ping_request = PingRequest { time }; Self::PingRequest(ping_request) } } + pub enum StatusClientBoundPacket { StatusResponse(StatusResponse), - PingResponse(PingResponse) + PingResponse(PingResponse), } impl StatusClientBoundPacket { pub fn get_type_id(&self) -> u8 { match self { Self::StatusResponse(_) => 0x00, - Self::PingResponse(_) => 0x01 + Self::PingResponse(_) => 0x01, } } @@ -68,39 +66,34 @@ impl StatusClientBoundPacket { Ok(Self::PingResponse(ping_response)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } pub fn status_response(response: String) -> Self { - let status_response = StatusResponse { - response - }; + let status_response = StatusResponse { response }; Self::StatusResponse(status_response) } pub fn ping_response(time: i64) -> Self { - let ping_response = PingResponse { - time - }; + let ping_response = PingResponse { time }; Self::PingResponse(ping_response) } } + #[derive(Packet, Debug)] pub struct PingRequest { - pub time: i64 + pub time: i64, } - #[derive(Packet, Debug)] pub struct StatusResponse { - pub response: String + pub response: String, } #[derive(Packet, Debug)] pub struct PingResponse { - pub time: i64 + pub time: i64, } - From 87b1e7a250df8f2e473076610ec2aab5665d23fc Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 16:46:00 +0300 Subject: [PATCH 12/22] Add field data type modification --- protocol-generator/src/data/output.rs | 20 +++++++++----- protocol-generator/src/main.rs | 28 +++++++++++++++----- protocol-generator/templates/packet_enum.hbs | 2 +- protocol/src/packet/status.rs | 5 ++-- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/data/output.rs index a5b5680..12d80f5 100644 --- a/protocol-generator/src/data/output.rs +++ b/protocol-generator/src/data/output.rs @@ -3,6 +3,7 @@ use std::collections::HashSet; use std::fmt; use std::fmt::Display; +#[derive(Debug)] pub enum State { Handshake, Status, @@ -13,10 +14,10 @@ pub enum State { impl State { pub fn data_import(&self) -> &str { match self { - State::Handshake => "crate::packet::handshake", - State::Status => "crate::packet::status", - State::Login => "crate::packet::login", - State::Game => "crate::packet::game", + State::Handshake => "crate::data::handshake::*", + State::Status => "crate::data::status::*", + State::Login => "crate::data::login::*", + State::Game => "crate::data::game::*", } } } @@ -50,7 +51,7 @@ impl Display for Bound { } } -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct Packet { pub id: u8, pub name: String, @@ -67,7 +68,7 @@ impl Packet { } } -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct Field { pub name: String, #[serde(flatten)] @@ -81,9 +82,13 @@ impl Field { data_type, } } + + pub fn change_type(&self, data_type: DataType) -> Field { + Field::new(&self.name, data_type) + } } -#[derive(Serialize, Eq, PartialEq)] +#[derive(Serialize, Eq, PartialEq, Debug)] #[serde(tag = "type")] pub enum DataType { #[serde(rename(serialize = "bool"))] @@ -137,6 +142,7 @@ impl DataType { } } +#[derive(Debug)] pub struct Protocol { pub state: State, pub server_bound_packets: Vec, diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index c09e7be..86dc94b 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -6,6 +6,7 @@ use heck::{CamelCase, SnakeCase}; use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::output; +use crate::data::output::Field; use serde::Serialize; use serde_json::json; use std::collections::HashMap; @@ -132,7 +133,7 @@ fn transform_protocol_data( let id = *packet_ids .get(no_prefix_name) .expect("Failed to get packet id"); - let name = rename_packet(&no_prefix_name.to_camel_case(), &bound); + let packet_name = rename_packet(&no_prefix_name.to_camel_case(), &bound); let mut fields = vec![]; @@ -142,14 +143,14 @@ fn transform_protocol_data( match container { Container::Value { name, data } => { if let Some(field) = transform_field(name, data) { - fields.push(field); + fields.push(modify_field(&packet_name, field)); } } Container::List { name, data_vec } => { if let Some(name) = name { for data in data_vec { if let Some(field) = transform_field(name, data) { - fields.push(field); + fields.push(modify_field(&packet_name, field)); } } } @@ -159,7 +160,11 @@ fn transform_protocol_data( } } - let packet = output::Packet { id, name, fields }; + let packet = output::Packet { + id, + name: packet_name, + fields, + }; packets.push(packet); } @@ -218,8 +223,8 @@ fn format_field_name(unformatted_field_name: &str) -> String { } } -fn transform_data_type(str_type: &str) -> Option { - match str_type { +fn transform_data_type(name: &str) -> Option { + match name { "bool" => Some(output::DataType::Boolean), "i8" => Some(output::DataType::Byte), "i16" => Some(output::DataType::Short), @@ -237,12 +242,21 @@ fn transform_data_type(str_type: &str) -> Option { "buffer" => Some(output::DataType::ByteArray { rest: false }), "restBuffer" => Some(output::DataType::ByteArray { rest: true }), _ => { - println!("{}", str_type); + println!("Unknown data type \"{}\"", name); None } } } +fn modify_field(packet_name: &str, field: output::Field) -> output::Field { + match (packet_name, field.name.as_str()) { + ("StatusResponse", "response") => field.change_type(output::DataType::RefType { + ref_name: "ServerStatus".to_owned(), + }), + _ => field, + } +} + fn rename_packet(name: &str, bound: &output::Bound) -> String { match (name, bound) { ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/packet_enum.hbs index 0b81503..c596a16 100644 --- a/protocol-generator/templates/packet_enum.hbs +++ b/protocol-generator/templates/packet_enum.hbs @@ -32,7 +32,7 @@ impl {{packet_enum_name}} { } } {{#each packets as |p|}} - pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{f.type}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { + pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{#if (ne f.type "RefType")}}{{f.type}}{{~else}}{{f.ref_name}}{{/if}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { {{~#if p.fields}} let {{snake_case p.name}} = {{p.name}} { {{~#each p.fields as |f|}} diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs index 4beb5be..6392a83 100644 --- a/protocol/src/packet/status.rs +++ b/protocol/src/packet/status.rs @@ -1,5 +1,6 @@ // This file is automatically generated. // It is not intended for manual editing. +use crate::data::status::*; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; @@ -70,7 +71,7 @@ impl StatusClientBoundPacket { } } - pub fn status_response(response: String) -> Self { + pub fn status_response(response: ServerStatus) -> Self { let status_response = StatusResponse { response }; Self::StatusResponse(status_response) @@ -90,7 +91,7 @@ pub struct PingRequest { #[derive(Packet, Debug)] pub struct StatusResponse { - pub response: String, + pub response: ServerStatus, } #[derive(Packet, Debug)] From 3be31e8b811a4bc04358edde0cf570855e12ad30 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 17:20:01 +0300 Subject: [PATCH 13/22] Add ref types to login and remove code coverage --- README.md | 1 - protocol-generator/src/main.rs | 26 ++++++++++++++------------ protocol/src/packet/login.rs | 11 +++++++---- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 560c9de..b5ef07f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,5 @@ minecraft-protocol ============ [![crates.io](https://img.shields.io/crates/v/minecraft-protocol.svg)](https://crates.io/crates/minecraft-protocol) [![Build Status](https://travis-ci.com/eihwaz/minecraft-protocol.svg?branch=master)](https://travis-ci.com/eihwaz/minecraft-protocol) -[![codecov](https://codecov.io/gh/eihwaz/minecraft-protocol/branch/master/graph/badge.svg)](https://codecov.io/gh/eihwaz/minecraft-protocol) Library for decoding and encoding Minecraft packets diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 86dc94b..8997047 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -50,8 +50,8 @@ pub fn main() { output::State::Login, ), // ( - // transform_protocol_state(State::Game, &protocol_input.game), - // State::Game, + // transform_protocol_state(output::State::Game, &protocol_input.game), + // output::State::Game, // ), ]; @@ -216,7 +216,7 @@ fn transform_field(unformatted_field_name: &str, data: &Data) -> Option String { - if unformatted_field_name == "Type" { + if unformatted_field_name == "type" { String::from("type_") } else { unformatted_field_name.to_snake_case() @@ -248,15 +248,6 @@ fn transform_data_type(name: &str) -> Option { } } -fn modify_field(packet_name: &str, field: output::Field) -> output::Field { - match (packet_name, field.name.as_str()) { - ("StatusResponse", "response") => field.change_type(output::DataType::RefType { - ref_name: "ServerStatus".to_owned(), - }), - _ => field, - } -} - fn rename_packet(name: &str, bound: &output::Bound) -> String { match (name, bound) { ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", @@ -270,6 +261,17 @@ fn rename_packet(name: &str, bound: &output::Bound) -> String { .to_owned() } +fn modify_field(packet_name: &str, field: output::Field) -> output::Field { + match (packet_name, field.name.as_str()) { + ("StatusResponse", "response") => field.change_type(output::DataType::RefType { + ref_name: "ServerStatus".to_owned(), + }), + ("Success", "uuid") => field.change_type(output::DataType::Uuid { hyphenated: true }), + ("Disconnect", "reason") => field.change_type(output::DataType::Chat), + _ => field, + } +} + #[derive(Serialize)] struct GenerateContext<'a> { packet_enum_name: String, diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs index 4414da5..8c3fc7f 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/packet/login.rs @@ -1,9 +1,11 @@ // This file is automatically generated. // It is not intended for manual editing. +use crate::chat::Message; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; use std::io::Read; +use uuid::Uuid; pub enum LoginServerBoundPacket { LoginStart(LoginStart), @@ -113,7 +115,7 @@ impl LoginClientBoundPacket { } } - pub fn disconnect(reason: String) -> Self { + pub fn disconnect(reason: Chat) -> Self { let disconnect = Disconnect { reason }; Self::Disconnect(disconnect) @@ -133,7 +135,7 @@ impl LoginClientBoundPacket { Self::EncryptionRequest(encryption_request) } - pub fn success(uuid: String, username: String) -> Self { + pub fn success(uuid: Uuid, username: String) -> Self { let success = Success { uuid, username }; Self::Success(success) @@ -177,7 +179,7 @@ pub struct LoginPluginResponse { #[derive(Packet, Debug)] pub struct Disconnect { - pub reason: String, + pub reason: Chat, } #[derive(Packet, Debug)] @@ -189,7 +191,8 @@ pub struct EncryptionRequest { #[derive(Packet, Debug)] pub struct Success { - pub uuid: String, + #[packet(with = "uuid_hyp_str")] + pub uuid: Uuid, pub username: String, } From 0a0835fd2d3ee674aa2a84bff9cb8274510dc004 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 18:40:11 +0300 Subject: [PATCH 14/22] Add game packets --- .travis.yml | 24 - protocol-generator/src/data/output.rs | 3 +- protocol-generator/src/main.rs | 73 +- protocol/src/packet/game.rs | 3467 ++++++++++++++++++++++++- protocol/src/packet/login.rs | 70 +- 5 files changed, 3481 insertions(+), 156 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99c3ad3..e428e05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,27 +7,3 @@ rust: matrix: allow_failures: - rust: nightly -addons: - apt: - packages: - - libcurl4-openssl-dev - - libelf-dev - - libdw-dev - - cmake - - gcc - - binutils-dev - - libiberty-dev -after_success: | - wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && - tar xzf master.tar.gz && - cd kcov-master && - mkdir build && - cd build && - cmake .. && - make && - make install DESTDIR=../../kcov-build && - cd ../.. && - rm -rf kcov-master && - for file in target/debug/minecraft_protocol*; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done && - bash <(curl -s https://codecov.io/bash) && - echo "Uploaded code coverage" diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/data/output.rs index 12d80f5..91c0ece 100644 --- a/protocol-generator/src/data/output.rs +++ b/protocol-generator/src/data/output.rs @@ -127,6 +127,7 @@ pub enum DataType { RefType { ref_name: String, }, + #[serde(rename(serialize = "Message"))] Chat, } @@ -136,7 +137,7 @@ impl DataType { DataType::Uuid { .. } => Some("uuid::Uuid"), DataType::CompoundTag => Some("nbt::CompoundTag"), DataType::RefType { .. } => Some(state.data_import()), - DataType::Chat => Some("crate::chat::Message"), + DataType::Chat => Some("crate::data::chat::Message"), _ => None, } } diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 8997047..c25e9a0 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -6,7 +6,6 @@ use heck::{CamelCase, SnakeCase}; use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::output; -use crate::data::output::Field; use serde::Serialize; use serde_json::json; use std::collections::HashMap; @@ -49,10 +48,10 @@ pub fn main() { transform_protocol_state(output::State::Login, &protocol_input.login), output::State::Login, ), - // ( - // transform_protocol_state(output::State::Game, &protocol_input.game), - // output::State::Game, - // ), + ( + transform_protocol_state(output::State::Game, &protocol_input.game), + output::State::Game, + ), ]; for (protocol, state) in protocols { @@ -102,10 +101,16 @@ fn transform_protocol_state( state: output::State, protocol_state: &ProtocolState, ) -> output::Protocol { - let server_bound_packets = - transform_protocol_data(&protocol_state.to_server, output::Bound::Server); - let client_bound_packets = - transform_protocol_data(&protocol_state.to_client, output::Bound::Client); + let server_bound_packets = transform_protocol_data( + protocol_state, + &protocol_state.to_server, + output::Bound::Server, + ); + let client_bound_packets = transform_protocol_data( + protocol_state, + &protocol_state.to_client, + output::Bound::Client, + ); output::Protocol { state, @@ -115,6 +120,7 @@ fn transform_protocol_state( } fn transform_protocol_data( + protocol_state: &ProtocolState, protocol_data: &ProtocolData, bound: output::Bound, ) -> Vec { @@ -128,12 +134,18 @@ fn transform_protocol_data( continue; } - let no_prefix_name = unformatted_name.trim_start_matches("packet_"); + let no_prefix_unformatted = unformatted_name.trim_start_matches("packet_"); let id = *packet_ids - .get(no_prefix_name) + .get(no_prefix_unformatted) .expect("Failed to get packet id"); - let packet_name = rename_packet(&no_prefix_name.to_camel_case(), &bound); + + let packet_name = rename_packet( + unformatted_name, + &no_prefix_unformatted.to_camel_case(), + &bound, + protocol_state, + ); let mut fields = vec![]; @@ -248,8 +260,13 @@ fn transform_data_type(name: &str) -> Option { } } -fn rename_packet(name: &str, bound: &output::Bound) -> String { - match (name, bound) { +fn rename_packet( + unformatted_name: &str, + name: &str, + bound: &output::Bound, + protocol_state: &ProtocolState, +) -> String { + let new_name = match (name, bound) { ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", ("EncryptionBegin", output::Bound::Client) => "EncryptionRequest", ("PingStart", output::Bound::Server) => "StatusRequest", @@ -258,7 +275,29 @@ fn rename_packet(name: &str, bound: &output::Bound) -> String { ("Ping", output::Bound::Client) => "PingResponse", _ => name, } - .to_owned() + .to_owned(); + + if new_name == name + && protocol_state + .to_client + .types + .contains_key(unformatted_name) + && protocol_state + .to_server + .types + .contains_key(unformatted_name) + { + bidirectional(&new_name, bound) + } else { + new_name.to_owned() + } +} + +fn bidirectional(name: &str, bound: &output::Bound) -> String { + match bound { + output::Bound::Server => format!("ServerBound{}", name), + output::Bound::Client => format!("ClientBound{}", name), + } } fn modify_field(packet_name: &str, field: output::Field) -> output::Field { @@ -268,6 +307,10 @@ fn modify_field(packet_name: &str, field: output::Field) -> output::Field { }), ("Success", "uuid") => field.change_type(output::DataType::Uuid { hyphenated: true }), ("Disconnect", "reason") => field.change_type(output::DataType::Chat), + ("ClientBoundChatMessage", "message") => field.change_type(output::DataType::Chat), + ("ClientBoundChatMessage", "position") => field.change_type(output::DataType::RefType { + ref_name: "MessagePosition".to_owned(), + }), _ => field, } } diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs index bb8e585..85bf5ee 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/packet/game.rs @@ -1,140 +1,3435 @@ -use crate::data::chat::Message; -use crate::data::game::{GameMode, MessagePosition}; +// This file is automatically generated. +// It is not intended for manual editing. use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; use nbt::CompoundTag; use std::io::Read; +use uuid::Uuid; pub enum GameServerBoundPacket { - ServerBoundChatMessage(ServerBoundChatMessage), + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl GameServerBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32) -> Self { + let query_block_nbt = QueryBlockNbt { transaction_id }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(signing: bool, hand: i32) -> Self { + let edit_book = EditBook { signing, hand }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click(window_id: u8, slot: i16, mouse_button: i8, action: i16, mode: i8) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, face: i8) -> Self { + let block_dig = BlockDig { status, face }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16) -> Self { + let set_creative_slot = SetCreativeSlot { slot }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign(text1: String, text2: String, text3: String, text4: String) -> Self { + let update_sign = UpdateSign { + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } } pub enum GameClientBoundPacket { - ClientBoundChatMessage(ClientBoundChatMessage), - JoinGame(JoinGame), + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), ClientBoundKeepAlive(ClientBoundKeepAlive), - ChunkData(ChunkData), - GameDisconnect(GameDisconnect), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + Login(Login), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity, + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition, + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags, + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl GameClientBoundPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::Login(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x42, + Self::EntityMetadata(_) => 0x43, + Self::AttachEntity(_) => 0x44, + Self::EntityVelocity(_) => 0x45, + Self::EntityEquipment(_) => 0x46, + Self::Experience(_) => 0x47, + Self::UpdateHealth(_) => 0x48, + Self::ScoreboardObjective(_) => 0x49, + Self::SetPassengers(_) => 0x4A, + Self::Teams(_) => 0x4B, + Self::ScoreboardScore(_) => 0x4C, + Self::SpawnPosition => 0x4D, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags => 0x5B, + Self::AcknowledgePlayerDigging(_) => 0x5C, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let login = Login::decode(reader)?; + + Ok(Self::Login(login)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => Ok(Self::OpenSignEntity), + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x42 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x43 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x44 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x45 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x46 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x47 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x48 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x49 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4A => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4B => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4C => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4D => Ok(Self::SpawnPosition), + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => Ok(Self::Tags), + 0x5C => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { action, nbt_data }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(type_: i32) -> Self { + let block_change = BlockChange { type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16) -> Self { + let set_slot = SetSlot { window_id, slot }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn login( + entity_id: i32, + game_mode: u8, + dimension: i32, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + ) -> Self { + let login = Login { + entity_id, + game_mode, + dimension, + max_players, + level_type, + view_distance, + reduced_debug_info, + }; + + Self::Login(login) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity() -> Self { + Self::OpenSignEntity + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32) -> Self { + let entity_metadata = EntityMetadata { entity_id }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32) -> Self { + let entity_equipment = EntityEquipment { entity_id, slot }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position() -> Self { + Self::SpawnPosition + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags() -> Self { + Self::Tags + } + + pub fn acknowledge_player_digging(block: i32, status: i32, successful: bool) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, } -impl GameServerBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03, - GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F, - } - } +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, +} - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x03 => { - let chat_message = ServerBoundChatMessage::decode(reader)?; +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} - Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message)) - } - 0x0F => { - let keep_alive = ServerBoundKeepAlive::decode(reader)?; +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} - Ok(GameServerBoundPacket::ServerBoundKeepAlive(keep_alive)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, } -impl GameClientBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E, - GameClientBoundPacket::GameDisconnect(_) => 0x1A, - GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20, - GameClientBoundPacket::ChunkData(_) => 0x21, - GameClientBoundPacket::JoinGame(_) => 0x25, - } - } +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x0E => { - let chat_message = ClientBoundChatMessage::decode(reader)?; +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} - Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message)) - } - 0x1A => { - let game_disconnect = GameDisconnect::decode(reader)?; +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} - Ok(GameClientBoundPacket::GameDisconnect(game_disconnect)) - } - 0x20 => { - let keep_alive = ClientBoundKeepAlive::decode(reader)?; +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} - Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive)) - } - 0x21 => { - let chunk_data = ChunkData::decode(reader)?; +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} - Ok(GameClientBoundPacket::ChunkData(chunk_data)) - } - 0x25 => { - let join_game = JoinGame::decode(reader)?; +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} - Ok(GameClientBoundPacket::JoinGame(join_game)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, } #[derive(Packet, Debug)] -pub struct ServerBoundChatMessage { - #[packet(max_length = 256)] - pub message: String, +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, } #[derive(Packet, Debug)] -pub struct ClientBoundChatMessage { - pub message: Message, - pub position: MessagePosition, +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, } #[derive(Packet, Debug)] -pub struct JoinGame { - pub entity_id: u32, - pub game_mode: GameMode, +pub struct Login { + pub entity_id: i32, + pub game_mode: u8, pub dimension: i32, pub max_players: u8, - #[packet(max_length = 16)] pub level_type: String, #[packet(with = "var_int")] pub view_distance: i32, pub reduced_debug_info: bool, } -#[derive(Packet)] -pub struct ServerBoundKeepAlive { - pub id: u64, +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, } -#[derive(Packet)] -pub struct ClientBoundKeepAlive { - pub id: u64, +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, } #[derive(Packet, Debug)] -pub struct ChunkData { +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, pub x: i32, + pub y: i32, pub z: i32, - pub full: bool, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { #[packet(with = "var_int")] - pub primary_mask: i32, - pub heights: CompoundTag, - pub data: Vec, - pub tiles: Vec, + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, } #[derive(Packet, Debug)] -pub struct GameDisconnect { - pub reason: Message, +pub struct AcknowledgePlayerDigging { + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, } diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs index 8c3fc7f..0f43adf 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/packet/login.rs @@ -1,16 +1,16 @@ // This file is automatically generated. // It is not intended for manual editing. -use crate::chat::Message; use crate::DecodeError; use crate::Decoder; -use minecraft_protocol_derive::Packet; use std::io::Read; +use minecraft_protocol_derive::Packet; use uuid::Uuid; +use crate::data::chat::Message; pub enum LoginServerBoundPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), - LoginPluginResponse(LoginPluginResponse), + LoginPluginResponse(LoginPluginResponse) } impl LoginServerBoundPacket { @@ -18,7 +18,7 @@ impl LoginServerBoundPacket { match self { Self::LoginStart(_) => 0x00, Self::EncryptionResponse(_) => 0x01, - Self::LoginPluginResponse(_) => 0x02, + Self::LoginPluginResponse(_) => 0x02 } } @@ -39,12 +39,14 @@ impl LoginServerBoundPacket { Ok(Self::LoginPluginResponse(login_plugin_response)) } - _ => Err(DecodeError::UnknownPacketType { type_id }), + _ => Err(DecodeError::UnknownPacketType { type_id }) } } pub fn login_start(username: String) -> Self { - let login_start = LoginStart { username }; + let login_start = LoginStart { + username + }; Self::LoginStart(login_start) } @@ -52,14 +54,17 @@ impl LoginServerBoundPacket { pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { let encryption_response = EncryptionResponse { shared_secret, - verify_token, + verify_token }; Self::EncryptionResponse(encryption_response) } pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { - let login_plugin_response = LoginPluginResponse { message_id, data }; + let login_plugin_response = LoginPluginResponse { + message_id, + data + }; Self::LoginPluginResponse(login_plugin_response) } @@ -70,7 +75,7 @@ pub enum LoginClientBoundPacket { EncryptionRequest(EncryptionRequest), Success(Success), Compress(Compress), - LoginPluginRequest(LoginPluginRequest), + LoginPluginRequest(LoginPluginRequest) } impl LoginClientBoundPacket { @@ -80,7 +85,7 @@ impl LoginClientBoundPacket { Self::EncryptionRequest(_) => 0x01, Self::Success(_) => 0x02, Self::Compress(_) => 0x03, - Self::LoginPluginRequest(_) => 0x04, + Self::LoginPluginRequest(_) => 0x04 } } @@ -111,38 +116,41 @@ impl LoginClientBoundPacket { Ok(Self::LoginPluginRequest(login_plugin_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }), + _ => Err(DecodeError::UnknownPacketType { type_id }) } } - pub fn disconnect(reason: Chat) -> Self { - let disconnect = Disconnect { reason }; + pub fn disconnect(reason: Message) -> Self { + let disconnect = Disconnect { + reason + }; Self::Disconnect(disconnect) } - pub fn encryption_request( - server_id: String, - public_key: Vec, - verify_token: Vec, - ) -> Self { + pub fn encryption_request(server_id: String, public_key: Vec, verify_token: Vec) -> Self { let encryption_request = EncryptionRequest { server_id, public_key, - verify_token, + verify_token }; Self::EncryptionRequest(encryption_request) } pub fn success(uuid: Uuid, username: String) -> Self { - let success = Success { uuid, username }; + let success = Success { + uuid, + username + }; Self::Success(success) } pub fn compress(threshold: i32) -> Self { - let compress = Compress { threshold }; + let compress = Compress { + threshold + }; Self::Compress(compress) } @@ -151,7 +159,7 @@ impl LoginClientBoundPacket { let login_plugin_request = LoginPluginRequest { message_id, channel, - data, + data }; Self::LoginPluginRequest(login_plugin_request) @@ -160,13 +168,13 @@ impl LoginClientBoundPacket { #[derive(Packet, Debug)] pub struct LoginStart { - pub username: String, + pub username: String } #[derive(Packet, Debug)] pub struct EncryptionResponse { pub shared_secret: Vec, - pub verify_token: Vec, + pub verify_token: Vec } #[derive(Packet, Debug)] @@ -174,32 +182,33 @@ pub struct LoginPluginResponse { #[packet(with = "var_int")] pub message_id: i32, #[packet(with = "rest")] - pub data: Vec, + pub data: Vec } + #[derive(Packet, Debug)] pub struct Disconnect { - pub reason: Chat, + pub reason: Message } #[derive(Packet, Debug)] pub struct EncryptionRequest { pub server_id: String, pub public_key: Vec, - pub verify_token: Vec, + pub verify_token: Vec } #[derive(Packet, Debug)] pub struct Success { #[packet(with = "uuid_hyp_str")] pub uuid: Uuid, - pub username: String, + pub username: String } #[derive(Packet, Debug)] pub struct Compress { #[packet(with = "var_int")] - pub threshold: i32, + pub threshold: i32 } #[derive(Packet, Debug)] @@ -208,5 +217,6 @@ pub struct LoginPluginRequest { pub message_id: i32, pub channel: String, #[packet(with = "rest")] - pub data: Vec, + pub data: Vec } + From 1d5f2112a72fb69a5406d837d97375f0c3c62cab Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 18:46:24 +0300 Subject: [PATCH 15/22] Fix --- protocol-generator/src/main.rs | 4 +- protocol/src/lib.rs | 56 ++++++++++++++++++++++++++++ protocol/src/packet/game.rs | 8 ++-- protocol/src/packet/login.rs | 68 +++++++++++++++------------------- 4 files changed, 92 insertions(+), 44 deletions(-) diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index c25e9a0..0b8c375 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -307,8 +307,8 @@ fn modify_field(packet_name: &str, field: output::Field) -> output::Field { }), ("Success", "uuid") => field.change_type(output::DataType::Uuid { hyphenated: true }), ("Disconnect", "reason") => field.change_type(output::DataType::Chat), - ("ClientBoundChatMessage", "message") => field.change_type(output::DataType::Chat), - ("ClientBoundChatMessage", "position") => field.change_type(output::DataType::RefType { + ("ClientBoundChat", "message") => field.change_type(output::DataType::Chat), + ("ClientBoundChat", "position") => field.change_type(output::DataType::RefType { ref_name: "MessagePosition".to_owned(), }), _ => field, diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index e7eee2b..fdcbbc2 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -225,6 +225,20 @@ impl DecoderReadExt for R { read_signed_var_int!(i64, read_var_i64, 10); } +impl Encoder for i8 { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + Ok(writer.write_i8(*self)?) + } +} + +impl Decoder for i8 { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + Ok(reader.read_i8()?) + } +} + impl Encoder for u8 { fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { Ok(writer.write_u8(*self)?) @@ -239,6 +253,20 @@ impl Decoder for u8 { } } +impl Encoder for i16 { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + Ok(writer.write_i16::(*self)?) + } +} + +impl Decoder for i16 { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + Ok(reader.read_i16::()?) + } +} + impl Encoder for u16 { fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { Ok(writer.write_u16::(*self)?) @@ -337,6 +365,34 @@ impl Decoder for bool { } } +impl Encoder for f32 { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + Ok(writer.write_f32::(*self)?) + } +} + +impl Decoder for f32 { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + Ok(reader.read_f32::()?) + } +} + +impl Encoder for f64 { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + Ok(writer.write_f64::(*self)?) + } +} + +impl Decoder for f64 { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + Ok(reader.read_f64::()?) + } +} + impl Encoder for Vec { fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { Ok(writer.write_byte_array(self)?) diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs index 85bf5ee..3441fcb 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/packet/game.rs @@ -1,5 +1,7 @@ // This file is automatically generated. // It is not intended for manual editing. +use crate::data::chat::Message; +use crate::data::game::*; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; @@ -1641,7 +1643,7 @@ impl GameClientBoundPacket { Self::NbtQueryResponse(nbt_query_response) } - pub fn client_bound_chat(message: String, position: i8) -> Self { + pub fn client_bound_chat(message: Message, position: MessagePosition) -> Self { let client_bound_chat = ClientBoundChat { message, position }; Self::ClientBoundChat(client_bound_chat) @@ -2892,8 +2894,8 @@ pub struct NbtQueryResponse { #[derive(Packet, Debug)] pub struct ClientBoundChat { - pub message: String, - pub position: i8, + pub message: Message, + pub position: MessagePosition, } #[derive(Packet, Debug)] diff --git a/protocol/src/packet/login.rs b/protocol/src/packet/login.rs index 0f43adf..bb548cd 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/packet/login.rs @@ -1,16 +1,16 @@ // This file is automatically generated. // It is not intended for manual editing. +use crate::data::chat::Message; use crate::DecodeError; use crate::Decoder; -use std::io::Read; use minecraft_protocol_derive::Packet; +use std::io::Read; use uuid::Uuid; -use crate::data::chat::Message; pub enum LoginServerBoundPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), - LoginPluginResponse(LoginPluginResponse) + LoginPluginResponse(LoginPluginResponse), } impl LoginServerBoundPacket { @@ -18,7 +18,7 @@ impl LoginServerBoundPacket { match self { Self::LoginStart(_) => 0x00, Self::EncryptionResponse(_) => 0x01, - Self::LoginPluginResponse(_) => 0x02 + Self::LoginPluginResponse(_) => 0x02, } } @@ -39,14 +39,12 @@ impl LoginServerBoundPacket { Ok(Self::LoginPluginResponse(login_plugin_response)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } pub fn login_start(username: String) -> Self { - let login_start = LoginStart { - username - }; + let login_start = LoginStart { username }; Self::LoginStart(login_start) } @@ -54,17 +52,14 @@ impl LoginServerBoundPacket { pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { let encryption_response = EncryptionResponse { shared_secret, - verify_token + verify_token, }; Self::EncryptionResponse(encryption_response) } pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { - let login_plugin_response = LoginPluginResponse { - message_id, - data - }; + let login_plugin_response = LoginPluginResponse { message_id, data }; Self::LoginPluginResponse(login_plugin_response) } @@ -75,7 +70,7 @@ pub enum LoginClientBoundPacket { EncryptionRequest(EncryptionRequest), Success(Success), Compress(Compress), - LoginPluginRequest(LoginPluginRequest) + LoginPluginRequest(LoginPluginRequest), } impl LoginClientBoundPacket { @@ -85,7 +80,7 @@ impl LoginClientBoundPacket { Self::EncryptionRequest(_) => 0x01, Self::Success(_) => 0x02, Self::Compress(_) => 0x03, - Self::LoginPluginRequest(_) => 0x04 + Self::LoginPluginRequest(_) => 0x04, } } @@ -116,41 +111,38 @@ impl LoginClientBoundPacket { Ok(Self::LoginPluginRequest(login_plugin_request)) } - _ => Err(DecodeError::UnknownPacketType { type_id }) + _ => Err(DecodeError::UnknownPacketType { type_id }), } } pub fn disconnect(reason: Message) -> Self { - let disconnect = Disconnect { - reason - }; + let disconnect = Disconnect { reason }; Self::Disconnect(disconnect) } - pub fn encryption_request(server_id: String, public_key: Vec, verify_token: Vec) -> Self { + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { let encryption_request = EncryptionRequest { server_id, public_key, - verify_token + verify_token, }; Self::EncryptionRequest(encryption_request) } pub fn success(uuid: Uuid, username: String) -> Self { - let success = Success { - uuid, - username - }; + let success = Success { uuid, username }; Self::Success(success) } pub fn compress(threshold: i32) -> Self { - let compress = Compress { - threshold - }; + let compress = Compress { threshold }; Self::Compress(compress) } @@ -159,7 +151,7 @@ impl LoginClientBoundPacket { let login_plugin_request = LoginPluginRequest { message_id, channel, - data + data, }; Self::LoginPluginRequest(login_plugin_request) @@ -168,13 +160,13 @@ impl LoginClientBoundPacket { #[derive(Packet, Debug)] pub struct LoginStart { - pub username: String + pub username: String, } #[derive(Packet, Debug)] pub struct EncryptionResponse { pub shared_secret: Vec, - pub verify_token: Vec + pub verify_token: Vec, } #[derive(Packet, Debug)] @@ -182,33 +174,32 @@ pub struct LoginPluginResponse { #[packet(with = "var_int")] pub message_id: i32, #[packet(with = "rest")] - pub data: Vec + pub data: Vec, } - #[derive(Packet, Debug)] pub struct Disconnect { - pub reason: Message + pub reason: Message, } #[derive(Packet, Debug)] pub struct EncryptionRequest { pub server_id: String, pub public_key: Vec, - pub verify_token: Vec + pub verify_token: Vec, } #[derive(Packet, Debug)] pub struct Success { #[packet(with = "uuid_hyp_str")] pub uuid: Uuid, - pub username: String + pub username: String, } #[derive(Packet, Debug)] pub struct Compress { #[packet(with = "var_int")] - pub threshold: i32 + pub threshold: i32, } #[derive(Packet, Debug)] @@ -217,6 +208,5 @@ pub struct LoginPluginRequest { pub message_id: i32, pub channel: String, #[packet(with = "rest")] - pub data: Vec + pub data: Vec, } - From 5245cdf16dff8b39f9368f9b1f5b93d0ef5648fc Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Mon, 8 Feb 2021 01:49:30 +0300 Subject: [PATCH 16/22] Add more types and improve debug println --- protocol-generator/src/main.rs | 54 +++++--- protocol/src/data/game.rs | 129 ++++++++++++++++++- protocol/src/packet/game.rs | 227 ++++++++++++++++++++++++++------- 3 files changed, 345 insertions(+), 65 deletions(-) diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 0b8c375..4820043 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -153,16 +153,24 @@ fn transform_protocol_data( if let Data::Container(container_vec) = data { for container in container_vec { match container { - Container::Value { name, data } => { - if let Some(field) = transform_field(name, data) { - fields.push(modify_field(&packet_name, field)); - } - } + Container::Value { name, data } => match transform_field(name, data) { + Some(field) => fields.push(modify_field(&packet_name, field)), + None => println!( + "[{}] Field \"{}\" are skipped ({:?}", + packet_name, name, data + ), + }, Container::List { name, data_vec } => { if let Some(name) = name { for data in data_vec { - if let Some(field) = transform_field(name, data) { - fields.push(modify_field(&packet_name, field)); + match transform_field(name, data) { + Some(field) => { + fields.push(modify_field(&packet_name, field)) + } + None => println!( + "[{}] Field \"{}\" are skipped ({:?})", + packet_name, name, data_vec + ), } } } @@ -216,7 +224,7 @@ fn get_packet_ids(protocol_data: &ProtocolData) -> HashMap { fn transform_field(unformatted_field_name: &str, data: &Data) -> Option { match data { - Data::Type(str_type) => match transform_data_type(str_type) { + Data::Type(name) => match transform_data_type(name) { Some(data_type) => Some(output::Field { name: format_field_name(unformatted_field_name), data_type, @@ -227,14 +235,6 @@ fn transform_field(unformatted_field_name: &str, data: &Data) -> Option String { - if unformatted_field_name == "type" { - String::from("type_") - } else { - unformatted_field_name.to_snake_case() - } -} - fn transform_data_type(name: &str) -> Option { match name { "bool" => Some(output::DataType::Boolean), @@ -253,6 +253,19 @@ fn transform_data_type(name: &str) -> Option { "UUID" => Some(output::DataType::Uuid { hyphenated: false }), "buffer" => Some(output::DataType::ByteArray { rest: false }), "restBuffer" => Some(output::DataType::ByteArray { rest: true }), + "position" => Some(output::DataType::RefType { + ref_name: "Position".to_string(), + }), + "slot" => Some(output::DataType::RefType { + ref_name: "Option".to_string(), + }), + "entityMetadata" => Some(output::DataType::RefType { + ref_name: "Metadata".to_string(), + }), + "tags" => Some(output::DataType::RefType { + ref_name: "TagsMap".to_string(), + }), + "option" => None, _ => { println!("Unknown data type \"{}\"", name); None @@ -260,6 +273,14 @@ fn transform_data_type(name: &str) -> Option { } } +fn format_field_name(unformatted_field_name: &str) -> String { + if unformatted_field_name == "type" { + String::from("type_") + } else { + unformatted_field_name.to_snake_case() + } +} + fn rename_packet( unformatted_name: &str, name: &str, @@ -273,6 +294,7 @@ fn rename_packet( ("Ping", output::Bound::Server) => "PingRequest", ("ServerInfo", output::Bound::Client) => "StatusResponse", ("Ping", output::Bound::Client) => "PingResponse", + ("Login", output::Bound::Client) => "JoinGame", _ => name, } .to_owned(); diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs index 3df1fb7..95e2fcb 100644 --- a/protocol/src/data/game.rs +++ b/protocol/src/data/game.rs @@ -1,5 +1,9 @@ -use crate::impl_enum_encoder_decoder; +use crate::error::{DecodeError, EncodeError}; +use crate::{impl_enum_encoder_decoder, Decoder, DecoderReadExt, Encoder, EncoderWriteExt}; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use nbt::CompoundTag; use num_derive::{FromPrimitive, ToPrimitive}; +use std::io::{Read, Write}; #[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] pub enum MessagePosition { @@ -20,3 +24,126 @@ pub enum GameMode { } impl_enum_encoder_decoder!(GameMode); + +#[derive(Debug, Eq, PartialEq)] +pub struct Position { + pub x: i32, + pub y: i16, + pub z: i32, +} + +impl Encoder for Position { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + let encoded_x = (self.x & 0x3FFFFFF) as i64; + let encoded_y = (self.y & 0xFFF) as i64; + let encoded_z = (self.z & 0x3FFFFFF) as i64; + + writer.write_i64::((encoded_x << 38) | (encoded_z << 12) | encoded_y)?; + Ok(()) + } +} + +impl Decoder for Position { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + let encoded = reader.read_i64::()?; + + let x = (encoded >> 38) as i32; + let y = (encoded & 0xFFF) as i16; + let z = (encoded << 26 >> 38) as i32; + + Ok(Position { x, y, z }) + } +} + +#[derive(Debug)] +pub struct Slot { + pub id: i32, + pub amount: u8, + pub compound_tag: CompoundTag, +} + +impl Encoder for Option { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + match self { + Some(slot) => { + writer.write_bool(true)?; + slot.encode(writer) + } + None => writer.write_bool(false), + } + } +} + +impl Decoder for Option { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + if reader.read_bool()? { + Ok(Some(Slot::decode(reader)?)) + } else { + Ok(None) + } + } +} + +impl Encoder for Slot { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + writer.write_var_i32(self.id)?; + writer.write_u8(self.amount)?; + writer.write_compound_tag(&self.compound_tag)?; + + Ok(()) + } +} + +impl Decoder for Slot { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + let id = reader.read_var_i32()?; + let amount = reader.read_u8()?; + let compound_tag = reader.read_compound_tag()?; + + Ok(Slot { + id, + amount, + compound_tag, + }) + } +} + +#[derive(Debug)] +pub struct Metadata {} + +impl Encoder for Metadata { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for Metadata { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} + +#[derive(Debug)] +pub struct TagsMap {} + +impl Encoder for TagsMap { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for TagsMap { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs index 3441fcb..290aea1 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/packet/game.rs @@ -354,8 +354,11 @@ impl GameServerBoundPacket { Self::TeleportConfirm(teleport_confirm) } - pub fn query_block_nbt(transaction_id: i32) -> Self { - let query_block_nbt = QueryBlockNbt { transaction_id }; + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; Self::QueryBlockNbt(query_block_nbt) } @@ -366,8 +369,12 @@ impl GameServerBoundPacket { Self::SetDifficulty(set_difficulty) } - pub fn edit_book(signing: bool, hand: i32) -> Self { - let edit_book = EditBook { signing, hand }; + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; Self::EditBook(edit_book) } @@ -408,8 +415,9 @@ impl GameServerBoundPacket { Self::SetBeaconEffect(set_beacon_effect) } - pub fn update_command_block(command: String, mode: i32, flags: u8) -> Self { + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { let update_command_block = UpdateCommandBlock { + location, command, mode, flags, @@ -433,6 +441,7 @@ impl GameServerBoundPacket { } pub fn update_structure_block( + location: Position, action: i32, mode: i32, name: String, @@ -450,6 +459,7 @@ impl GameServerBoundPacket { flags: u8, ) -> Self { let update_structure_block = UpdateStructureBlock { + location, action, mode, name, @@ -530,13 +540,21 @@ impl GameServerBoundPacket { Self::EnchantItem(enchant_item) } - pub fn window_click(window_id: u8, slot: i16, mouse_button: i8, action: i16, mode: i8) -> Self { + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { let window_click = WindowClick { window_id, slot, mouse_button, action, mode, + item, }; Self::WindowClick(window_click) @@ -648,8 +666,12 @@ impl GameServerBoundPacket { Self::ServerBoundAbilities(server_bound_abilities) } - pub fn block_dig(status: i8, face: i8) -> Self { - let block_dig = BlockDig { status, face }; + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; Self::BlockDig(block_dig) } @@ -692,18 +714,20 @@ impl GameServerBoundPacket { Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) } - pub fn set_creative_slot(slot: i16) -> Self { - let set_creative_slot = SetCreativeSlot { slot }; + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; Self::SetCreativeSlot(set_creative_slot) } pub fn update_jigsaw_block( + location: Position, attachment_type: String, target_pool: String, final_state: String, ) -> Self { let update_jigsaw_block = UpdateJigsawBlock { + location, attachment_type, target_pool, final_state, @@ -712,8 +736,15 @@ impl GameServerBoundPacket { Self::UpdateJigsawBlock(update_jigsaw_block) } - pub fn update_sign(text1: String, text2: String, text3: String, text4: String) -> Self { + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { let update_sign = UpdateSign { + location, text1, text2, text3, @@ -737,6 +768,7 @@ impl GameServerBoundPacket { pub fn block_place( hand: i32, + location: Position, direction: i32, cursor_x: f32, cursor_y: f32, @@ -745,6 +777,7 @@ impl GameServerBoundPacket { ) -> Self { let block_place = BlockPlace { hand, + location, direction, cursor_x, cursor_y, @@ -810,7 +843,7 @@ pub enum GameClientBoundPacket { WorldEvent(WorldEvent), WorldParticles(WorldParticles), UpdateLight(UpdateLight), - Login(Login), + JoinGame(JoinGame), Map(Map), TradeList(TradeList), RelEntityMove(RelEntityMove), @@ -819,7 +852,7 @@ pub enum GameClientBoundPacket { Entity(Entity), ClientBoundVehicleMove(ClientBoundVehicleMove), OpenBook(OpenBook), - OpenSignEntity, + OpenSignEntity(OpenSignEntity), CraftRecipeResponse(CraftRecipeResponse), ClientBoundAbilities(ClientBoundAbilities), CombatEvent(CombatEvent), @@ -847,7 +880,7 @@ pub enum GameClientBoundPacket { SetPassengers(SetPassengers), Teams(Teams), ScoreboardScore(ScoreboardScore), - SpawnPosition, + SpawnPosition(SpawnPosition), UpdateTime(UpdateTime), Title(Title), EntitySoundEffect(EntitySoundEffect), @@ -860,7 +893,7 @@ pub enum GameClientBoundPacket { EntityEffect(EntityEffect), SelectAdvancementTab(SelectAdvancementTab), DeclareRecipes, - Tags, + Tags(Tags), AcknowledgePlayerDigging(AcknowledgePlayerDigging), } @@ -908,7 +941,7 @@ impl GameClientBoundPacket { Self::WorldEvent(_) => 0x22, Self::WorldParticles(_) => 0x23, Self::UpdateLight(_) => 0x24, - Self::Login(_) => 0x25, + Self::JoinGame(_) => 0x25, Self::Map(_) => 0x26, Self::TradeList(_) => 0x27, Self::RelEntityMove(_) => 0x28, @@ -917,7 +950,7 @@ impl GameClientBoundPacket { Self::Entity(_) => 0x2B, Self::ClientBoundVehicleMove(_) => 0x2C, Self::OpenBook(_) => 0x2D, - Self::OpenSignEntity => 0x2F, + Self::OpenSignEntity(_) => 0x2F, Self::CraftRecipeResponse(_) => 0x30, Self::ClientBoundAbilities(_) => 0x31, Self::CombatEvent(_) => 0x32, @@ -945,7 +978,7 @@ impl GameClientBoundPacket { Self::SetPassengers(_) => 0x4A, Self::Teams(_) => 0x4B, Self::ScoreboardScore(_) => 0x4C, - Self::SpawnPosition => 0x4D, + Self::SpawnPosition(_) => 0x4D, Self::UpdateTime(_) => 0x4E, Self::Title(_) => 0x4F, Self::EntitySoundEffect(_) => 0x50, @@ -958,7 +991,7 @@ impl GameClientBoundPacket { Self::EntityEffect(_) => 0x59, Self::SelectAdvancementTab(_) => 0x3C, Self::DeclareRecipes => 0x5A, - Self::Tags => 0x5B, + Self::Tags(_) => 0x5B, Self::AcknowledgePlayerDigging(_) => 0x5C, } } @@ -1167,9 +1200,9 @@ impl GameClientBoundPacket { Ok(Self::UpdateLight(update_light)) } 0x25 => { - let login = Login::decode(reader)?; + let join_game = JoinGame::decode(reader)?; - Ok(Self::Login(login)) + Ok(Self::JoinGame(join_game)) } 0x26 => { let map = Map::decode(reader)?; @@ -1211,7 +1244,11 @@ impl GameClientBoundPacket { Ok(Self::OpenBook(open_book)) } - 0x2F => Ok(Self::OpenSignEntity), + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } 0x30 => { let craft_recipe_response = CraftRecipeResponse::decode(reader)?; @@ -1345,7 +1382,11 @@ impl GameClientBoundPacket { Ok(Self::ScoreboardScore(scoreboard_score)) } - 0x4D => Ok(Self::SpawnPosition), + 0x4D => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } 0x4E => { let update_time = UpdateTime::decode(reader)?; @@ -1402,7 +1443,11 @@ impl GameClientBoundPacket { Ok(Self::SelectAdvancementTab(select_advancement_tab)) } 0x5A => Ok(Self::DeclareRecipes), - 0x5B => Ok(Self::Tags), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } 0x5C => { let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; @@ -1481,6 +1526,7 @@ impl GameClientBoundPacket { velocity_x: i16, velocity_y: i16, velocity_z: i16, + metadata: Metadata, ) -> Self { let spawn_entity_living = SpawnEntityLiving { entity_id, @@ -1495,6 +1541,7 @@ impl GameClientBoundPacket { velocity_x, velocity_y, velocity_z, + metadata, }; Self::SpawnEntityLiving(spawn_entity_living) @@ -1504,12 +1551,14 @@ impl GameClientBoundPacket { entity_id: i32, entity_uuid: Uuid, title: i32, + location: Position, direction: u8, ) -> Self { let spawn_entity_painting = SpawnEntityPainting { entity_id, entity_uuid, title, + location, direction, }; @@ -1524,6 +1573,7 @@ impl GameClientBoundPacket { z: f64, yaw: i8, pitch: i8, + metadata: Metadata, ) -> Self { let named_entity_spawn = NamedEntitySpawn { entity_id, @@ -1533,6 +1583,7 @@ impl GameClientBoundPacket { z, yaw, pitch, + metadata, }; Self::NamedEntitySpawn(named_entity_spawn) @@ -1557,23 +1608,29 @@ impl GameClientBoundPacket { Self::Advancements(advancements) } - pub fn block_break_animation(entity_id: i32, destroy_stage: i8) -> Self { + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { let block_break_animation = BlockBreakAnimation { entity_id, + location, destroy_stage, }; Self::BlockBreakAnimation(block_break_animation) } - pub fn tile_entity_data(action: u8, nbt_data: CompoundTag) -> Self { - let tile_entity_data = TileEntityData { action, nbt_data }; + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; Self::TileEntityData(tile_entity_data) } - pub fn block_action(byte1: u8, byte2: u8, block_id: i32) -> Self { + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { let block_action = BlockAction { + location, byte1, byte2, block_id, @@ -1582,8 +1639,8 @@ impl GameClientBoundPacket { Self::BlockAction(block_action) } - pub fn block_change(type_: i32) -> Self { - let block_change = BlockChange { type_ }; + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; Self::BlockChange(block_change) } @@ -1697,8 +1754,12 @@ impl GameClientBoundPacket { Self::CraftProgressBar(craft_progress_bar) } - pub fn set_slot(window_id: i8, slot: i16) -> Self { - let set_slot = SetSlot { window_id, slot }; + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; Self::SetSlot(set_slot) } @@ -1825,9 +1886,10 @@ impl GameClientBoundPacket { Self::MapChunk(map_chunk) } - pub fn world_event(effect_id: i32, data: i32, global: bool) -> Self { + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { let world_event = WorldEvent { effect_id, + location, data, global, }; @@ -1885,7 +1947,7 @@ impl GameClientBoundPacket { Self::UpdateLight(update_light) } - pub fn login( + pub fn join_game( entity_id: i32, game_mode: u8, dimension: i32, @@ -1894,7 +1956,7 @@ impl GameClientBoundPacket { view_distance: i32, reduced_debug_info: bool, ) -> Self { - let login = Login { + let join_game = JoinGame { entity_id, game_mode, dimension, @@ -1904,7 +1966,7 @@ impl GameClientBoundPacket { reduced_debug_info, }; - Self::Login(login) + Self::JoinGame(join_game) } pub fn map( @@ -2012,8 +2074,10 @@ impl GameClientBoundPacket { Self::OpenBook(open_book) } - pub fn open_sign_entity() -> Self { - Self::OpenSignEntity + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) } pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { @@ -2158,8 +2222,11 @@ impl GameClientBoundPacket { Self::ScoreboardDisplayObjective(scoreboard_display_objective) } - pub fn entity_metadata(entity_id: i32) -> Self { - let entity_metadata = EntityMetadata { entity_id }; + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; Self::EntityMetadata(entity_metadata) } @@ -2189,8 +2256,12 @@ impl GameClientBoundPacket { Self::EntityVelocity(entity_velocity) } - pub fn entity_equipment(entity_id: i32, slot: i32) -> Self { - let entity_equipment = EntityEquipment { entity_id, slot }; + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; Self::EntityEquipment(entity_equipment) } @@ -2243,8 +2314,10 @@ impl GameClientBoundPacket { Self::ScoreboardScore(scoreboard_score) } - pub fn spawn_position() -> Self { - Self::SpawnPosition + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) } pub fn update_time(age: i64, time: i64) -> Self { @@ -2381,12 +2454,30 @@ impl GameClientBoundPacket { Self::DeclareRecipes } - pub fn tags() -> Self { - Self::Tags + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) } - pub fn acknowledge_player_digging(block: i32, status: i32, successful: bool) -> Self { + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { let acknowledge_player_digging = AcknowledgePlayerDigging { + location, block, status, successful, @@ -2406,6 +2497,7 @@ pub struct TeleportConfirm { pub struct QueryBlockNbt { #[packet(with = "var_int")] pub transaction_id: i32, + pub location: Position, } #[derive(Packet, Debug)] @@ -2415,6 +2507,7 @@ pub struct SetDifficulty { #[derive(Packet, Debug)] pub struct EditBook { + pub new_book: Option, pub signing: bool, #[packet(with = "var_int")] pub hand: i32, @@ -2455,6 +2548,7 @@ pub struct SetBeaconEffect { #[derive(Packet, Debug)] pub struct UpdateCommandBlock { + pub location: Position, pub command: String, #[packet(with = "var_int")] pub mode: i32, @@ -2471,6 +2565,7 @@ pub struct UpdateCommandBlockMinecart { #[derive(Packet, Debug)] pub struct UpdateStructureBlock { + pub location: Position, #[packet(with = "var_int")] pub action: i32, #[packet(with = "var_int")] @@ -2543,6 +2638,7 @@ pub struct WindowClick { pub mouse_button: i8, pub action: i16, pub mode: i8, + pub item: Option, } #[derive(Packet, Debug)] @@ -2637,6 +2733,7 @@ pub struct ServerBoundAbilities { #[derive(Packet, Debug)] pub struct BlockDig { pub status: i8, + pub location: Position, pub face: i8, } @@ -2677,10 +2774,12 @@ pub struct ServerBoundHeldItemSlot { #[derive(Packet, Debug)] pub struct SetCreativeSlot { pub slot: i16, + pub item: Option, } #[derive(Packet, Debug)] pub struct UpdateJigsawBlock { + pub location: Position, pub attachment_type: String, pub target_pool: String, pub final_state: String, @@ -2688,6 +2787,7 @@ pub struct UpdateJigsawBlock { #[derive(Packet, Debug)] pub struct UpdateSign { + pub location: Position, pub text1: String, pub text2: String, pub text3: String, @@ -2709,6 +2809,7 @@ pub struct Spectate { pub struct BlockPlace { #[packet(with = "var_int")] pub hand: i32, + pub location: Position, #[packet(with = "var_int")] pub direction: i32, pub cursor_x: f32, @@ -2783,6 +2884,7 @@ pub struct SpawnEntityLiving { pub velocity_x: i16, pub velocity_y: i16, pub velocity_z: i16, + pub metadata: Metadata, } #[derive(Packet, Debug)] @@ -2792,6 +2894,7 @@ pub struct SpawnEntityPainting { pub entity_uuid: Uuid, #[packet(with = "var_int")] pub title: i32, + pub location: Position, pub direction: u8, } @@ -2805,6 +2908,7 @@ pub struct NamedEntitySpawn { pub z: f64, pub yaw: i8, pub pitch: i8, + pub metadata: Metadata, } #[derive(Packet, Debug)] @@ -2823,17 +2927,20 @@ pub struct Advancements { pub struct BlockBreakAnimation { #[packet(with = "var_int")] pub entity_id: i32, + pub location: Position, pub destroy_stage: i8, } #[derive(Packet, Debug)] pub struct TileEntityData { + pub location: Position, pub action: u8, pub nbt_data: CompoundTag, } #[derive(Packet, Debug)] pub struct BlockAction { + pub location: Position, pub byte1: u8, pub byte2: u8, #[packet(with = "var_int")] @@ -2842,6 +2949,7 @@ pub struct BlockAction { #[derive(Packet, Debug)] pub struct BlockChange { + pub location: Position, #[packet(with = "var_int")] pub type_: i32, } @@ -2941,6 +3049,7 @@ pub struct CraftProgressBar { pub struct SetSlot { pub window_id: i8, pub slot: i16, + pub item: Option, } #[derive(Packet, Debug)] @@ -3031,6 +3140,7 @@ pub struct MapChunk { #[derive(Packet, Debug)] pub struct WorldEvent { pub effect_id: i32, + pub location: Position, pub data: i32, pub global: bool, } @@ -3068,7 +3178,7 @@ pub struct UpdateLight { } #[derive(Packet, Debug)] -pub struct Login { +pub struct JoinGame { pub entity_id: i32, pub game_mode: u8, pub dimension: i32, @@ -3153,6 +3263,11 @@ pub struct OpenBook { pub hand: i32, } +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + #[derive(Packet, Debug)] pub struct CraftRecipeResponse { pub window_id: i8, @@ -3268,6 +3383,7 @@ pub struct ScoreboardDisplayObjective { pub struct EntityMetadata { #[packet(with = "var_int")] pub entity_id: i32, + pub metadata: Metadata, } #[derive(Packet, Debug)] @@ -3291,6 +3407,7 @@ pub struct EntityEquipment { pub entity_id: i32, #[packet(with = "var_int")] pub slot: i32, + pub item: Option, } #[derive(Packet, Debug)] @@ -3335,6 +3452,11 @@ pub struct ScoreboardScore { pub score_name: String, } +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + #[derive(Packet, Debug)] pub struct UpdateTime { pub age: i64, @@ -3427,8 +3549,17 @@ pub struct SelectAdvancementTab { pub id: String, } +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + #[derive(Packet, Debug)] pub struct AcknowledgePlayerDigging { + pub location: Position, #[packet(with = "var_int")] pub block: i32, #[packet(with = "var_int")] From ebd8f5ce22f0d257f3f8c5b27cf27d5f24e2f5b9 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Mon, 8 Feb 2021 23:37:01 +0300 Subject: [PATCH 17/22] Refactor --- .../src/{data/input.rs => backend.rs} | 18 +- protocol-generator/src/data/mod.rs | 2 - protocol-generator/src/main.rs | 291 ++---------------- protocol-generator/src/mappings.rs | 65 ++++ protocol-generator/src/transformer.rs | 196 ++++++++++++ protocol/src/data/game.rs | 107 +------ protocol/src/lib.rs | 104 +++++++ 7 files changed, 404 insertions(+), 379 deletions(-) rename protocol-generator/src/{data/input.rs => backend.rs} (88%) delete mode 100644 protocol-generator/src/data/mod.rs create mode 100644 protocol-generator/src/mappings.rs create mode 100644 protocol-generator/src/transformer.rs diff --git a/protocol-generator/src/data/input.rs b/protocol-generator/src/backend.rs similarity index 88% rename from protocol-generator/src/data/input.rs rename to protocol-generator/src/backend.rs index b7a2c30..d8b3ced 100644 --- a/protocol-generator/src/data/input.rs +++ b/protocol-generator/src/backend.rs @@ -2,23 +2,23 @@ use linked_hash_map::LinkedHashMap; use serde::Deserialize; #[derive(Debug, Deserialize)] -pub struct Protocol { - pub handshaking: ProtocolState, - pub status: ProtocolState, - pub login: ProtocolState, +pub struct ProtocolHandler { + pub handshaking: Protocol, + pub status: Protocol, + pub login: Protocol, #[serde(rename = "play")] - pub game: ProtocolState, + pub game: Protocol, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct ProtocolState { - pub to_client: ProtocolData, - pub to_server: ProtocolData, +pub struct Protocol { + pub to_client: Packets, + pub to_server: Packets, } #[derive(Debug, Deserialize)] -pub struct ProtocolData { +pub struct Packets { pub types: LinkedHashMap>, } diff --git a/protocol-generator/src/data/mod.rs b/protocol-generator/src/data/mod.rs deleted file mode 100644 index 7d1a548..0000000 --- a/protocol-generator/src/data/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod input; -pub mod output; diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index 4820043..ffbd346 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -1,18 +1,19 @@ -mod data; +use std::fs::File; +use std::io::Write; -use crate::data::input; +use crate::mappings::CodeMappings; +use crate::transformer::transform_protocol; use handlebars::*; -use heck::{CamelCase, SnakeCase}; - -use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; -use crate::data::output; +use heck::SnakeCase; use serde::Serialize; use serde_json::json; -use std::collections::HashMap; -use std::fs::File; -use std::io::Write; use structopt::StructOpt; +pub mod backend; +pub mod frontend; +pub mod mappings; +pub mod transformer; + #[derive(StructOpt)] #[structopt(name = "protocol-generator")] struct Opt { @@ -32,25 +33,31 @@ pub fn main() { let protocol_data_file = File::open(protocol_data_file_name).expect("Failed to open protocol data file"); - let protocol_input: input::Protocol = + let protocol_input: backend::ProtocolHandler = serde_json::from_reader(protocol_data_file).expect("Failed to parse protocol data"); + let mappings = CodeMappings {}; + let protocols = vec![ ( - transform_protocol_state(output::State::Handshake, &protocol_input.handshaking), - output::State::Handshake, + transform_protocol( + &mappings, + frontend::State::Handshake, + &protocol_input.handshaking, + ), + frontend::State::Handshake, ), ( - transform_protocol_state(output::State::Status, &protocol_input.status), - output::State::Status, + transform_protocol(&mappings, frontend::State::Status, &protocol_input.status), + frontend::State::Status, ), ( - transform_protocol_state(output::State::Login, &protocol_input.login), - output::State::Login, + transform_protocol(&mappings, frontend::State::Login, &protocol_input.login), + frontend::State::Login, ), ( - transform_protocol_state(output::State::Game, &protocol_input.game), - output::State::Game, + transform_protocol(&mappings, frontend::State::Game, &protocol_input.game), + frontend::State::Game, ), ]; @@ -97,264 +104,24 @@ fn create_template_engine() -> Handlebars<'static> { template_engine } -fn transform_protocol_state( - state: output::State, - protocol_state: &ProtocolState, -) -> output::Protocol { - let server_bound_packets = transform_protocol_data( - protocol_state, - &protocol_state.to_server, - output::Bound::Server, - ); - let client_bound_packets = transform_protocol_data( - protocol_state, - &protocol_state.to_client, - output::Bound::Client, - ); - - output::Protocol { - state, - server_bound_packets, - client_bound_packets, - } -} - -fn transform_protocol_data( - protocol_state: &ProtocolState, - protocol_data: &ProtocolData, - bound: output::Bound, -) -> Vec { - let packet_ids = get_packet_ids(protocol_data); - let mut packets = vec![]; - - for (unformatted_name, data_vec) in protocol_data.types.iter() { - if !unformatted_name.starts_with("packet_") - || unformatted_name == "packet_legacy_server_list_ping" - { - continue; - } - - let no_prefix_unformatted = unformatted_name.trim_start_matches("packet_"); - - let id = *packet_ids - .get(no_prefix_unformatted) - .expect("Failed to get packet id"); - - let packet_name = rename_packet( - unformatted_name, - &no_prefix_unformatted.to_camel_case(), - &bound, - protocol_state, - ); - - let mut fields = vec![]; - - for data in data_vec { - if let Data::Container(container_vec) = data { - for container in container_vec { - match container { - Container::Value { name, data } => match transform_field(name, data) { - Some(field) => fields.push(modify_field(&packet_name, field)), - None => println!( - "[{}] Field \"{}\" are skipped ({:?}", - packet_name, name, data - ), - }, - Container::List { name, data_vec } => { - if let Some(name) = name { - for data in data_vec { - match transform_field(name, data) { - Some(field) => { - fields.push(modify_field(&packet_name, field)) - } - None => println!( - "[{}] Field \"{}\" are skipped ({:?})", - packet_name, name, data_vec - ), - } - } - } - } - } - } - } - } - - let packet = output::Packet { - id, - name: packet_name, - fields, - }; - - packets.push(packet); - } - - packets -} - -fn get_packet_ids(protocol_data: &ProtocolData) -> HashMap { - let reversed_packet_ids = protocol_data - .types - .get("packet") - .and_then(|d| d.get(1)) - .and_then(|d| match d { - Data::Container(data) => data.get(0), - _ => None, - }) - .and_then(|c| match c { - Container::List { data_vec, .. } => data_vec.get(1), - _ => None, - }) - .and_then(|d| match d { - Data::Mapper { mappings, .. } => Some(mappings), - _ => None, - }) - .expect("Failed to get packet ids"); - - reversed_packet_ids - .into_iter() - .map(|(k, v)| { - ( - v.clone(), - u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), - ) - }) - .collect() -} - -fn transform_field(unformatted_field_name: &str, data: &Data) -> Option { - match data { - Data::Type(name) => match transform_data_type(name) { - Some(data_type) => Some(output::Field { - name: format_field_name(unformatted_field_name), - data_type, - }), - None => None, - }, - _ => None, - } -} - -fn transform_data_type(name: &str) -> Option { - match name { - "bool" => Some(output::DataType::Boolean), - "i8" => Some(output::DataType::Byte), - "i16" => Some(output::DataType::Short), - "i32" => Some(output::DataType::Int { var_int: false }), - "i64" => Some(output::DataType::Long { var_long: false }), - "u8" => Some(output::DataType::UnsignedByte), - "u16" => Some(output::DataType::UnsignedShort), - "f32" => Some(output::DataType::Float), - "f64" => Some(output::DataType::Double), - "varint" => Some(output::DataType::Int { var_int: true }), - "varlong" => Some(output::DataType::Long { var_long: true }), - "string" => Some(output::DataType::String { max_length: 0 }), - "nbt" | "optionalNbt" => Some(output::DataType::CompoundTag), - "UUID" => Some(output::DataType::Uuid { hyphenated: false }), - "buffer" => Some(output::DataType::ByteArray { rest: false }), - "restBuffer" => Some(output::DataType::ByteArray { rest: true }), - "position" => Some(output::DataType::RefType { - ref_name: "Position".to_string(), - }), - "slot" => Some(output::DataType::RefType { - ref_name: "Option".to_string(), - }), - "entityMetadata" => Some(output::DataType::RefType { - ref_name: "Metadata".to_string(), - }), - "tags" => Some(output::DataType::RefType { - ref_name: "TagsMap".to_string(), - }), - "option" => None, - _ => { - println!("Unknown data type \"{}\"", name); - None - } - } -} - -fn format_field_name(unformatted_field_name: &str) -> String { - if unformatted_field_name == "type" { - String::from("type_") - } else { - unformatted_field_name.to_snake_case() - } -} - -fn rename_packet( - unformatted_name: &str, - name: &str, - bound: &output::Bound, - protocol_state: &ProtocolState, -) -> String { - let new_name = match (name, bound) { - ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", - ("EncryptionBegin", output::Bound::Client) => "EncryptionRequest", - ("PingStart", output::Bound::Server) => "StatusRequest", - ("Ping", output::Bound::Server) => "PingRequest", - ("ServerInfo", output::Bound::Client) => "StatusResponse", - ("Ping", output::Bound::Client) => "PingResponse", - ("Login", output::Bound::Client) => "JoinGame", - _ => name, - } - .to_owned(); - - if new_name == name - && protocol_state - .to_client - .types - .contains_key(unformatted_name) - && protocol_state - .to_server - .types - .contains_key(unformatted_name) - { - bidirectional(&new_name, bound) - } else { - new_name.to_owned() - } -} - -fn bidirectional(name: &str, bound: &output::Bound) -> String { - match bound { - output::Bound::Server => format!("ServerBound{}", name), - output::Bound::Client => format!("ClientBound{}", name), - } -} - -fn modify_field(packet_name: &str, field: output::Field) -> output::Field { - match (packet_name, field.name.as_str()) { - ("StatusResponse", "response") => field.change_type(output::DataType::RefType { - ref_name: "ServerStatus".to_owned(), - }), - ("Success", "uuid") => field.change_type(output::DataType::Uuid { hyphenated: true }), - ("Disconnect", "reason") => field.change_type(output::DataType::Chat), - ("ClientBoundChat", "message") => field.change_type(output::DataType::Chat), - ("ClientBoundChat", "position") => field.change_type(output::DataType::RefType { - ref_name: "MessagePosition".to_owned(), - }), - _ => field, - } -} - #[derive(Serialize)] struct GenerateContext<'a> { packet_enum_name: String, - packets: &'a Vec, + packets: &'a Vec, } fn generate_rust_file( - protocol: &output::Protocol, + protocol: &frontend::Protocol, template_engine: &Handlebars, mut writer: W, ) -> Result<(), TemplateRenderError> { let server_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, output::Bound::Server), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server), packets: &protocol.server_bound_packets, }; let client_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, output::Bound::Client), + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client), packets: &protocol.client_bound_packets, }; diff --git a/protocol-generator/src/mappings.rs b/protocol-generator/src/mappings.rs new file mode 100644 index 0000000..5716322 --- /dev/null +++ b/protocol-generator/src/mappings.rs @@ -0,0 +1,65 @@ +use crate::backend; +use crate::frontend; + +pub trait Mappings { + fn rename_packet( + &self, + unformatted_name: &str, + name: &str, + bound: &frontend::Bound, + protocol: &backend::Protocol, + ) -> String; + + fn change_field_type(&self, packet_name: &str, field: frontend::Field) -> frontend::Field; +} + +pub struct CodeMappings {} + +impl Mappings for CodeMappings { + fn rename_packet( + &self, + unformatted_name: &str, + name: &str, + bound: &frontend::Bound, + protocol: &backend::Protocol, + ) -> String { + let new_name = match (name, bound) { + ("EncryptionBegin", frontend::Bound::Server) => "EncryptionResponse", + ("EncryptionBegin", frontend::Bound::Client) => "EncryptionRequest", + ("PingStart", frontend::Bound::Server) => "StatusRequest", + ("Ping", frontend::Bound::Server) => "PingRequest", + ("ServerInfo", frontend::Bound::Client) => "StatusResponse", + ("Ping", frontend::Bound::Client) => "PingResponse", + ("Login", frontend::Bound::Client) => "JoinGame", + _ => name, + } + .to_owned(); + + if new_name == name + && protocol.to_client.types.contains_key(unformatted_name) + && protocol.to_server.types.contains_key(unformatted_name) + { + match bound { + frontend::Bound::Server => format!("ServerBound{}", name), + frontend::Bound::Client => format!("ClientBound{}", name), + } + } else { + new_name.to_owned() + } + } + + fn change_field_type(&self, packet_name: &str, field: frontend::Field) -> frontend::Field { + match (packet_name, field.name.as_str()) { + ("StatusResponse", "response") => field.change_type(frontend::DataType::RefType { + ref_name: "ServerStatus".to_owned(), + }), + ("Success", "uuid") => field.change_type(frontend::DataType::Uuid { hyphenated: true }), + ("Disconnect", "reason") => field.change_type(frontend::DataType::Chat), + ("ClientBoundChat", "message") => field.change_type(frontend::DataType::Chat), + ("ClientBoundChat", "position") => field.change_type(frontend::DataType::RefType { + ref_name: "MessagePosition".to_owned(), + }), + _ => field, + } + } +} diff --git a/protocol-generator/src/transformer.rs b/protocol-generator/src/transformer.rs new file mode 100644 index 0000000..20cb518 --- /dev/null +++ b/protocol-generator/src/transformer.rs @@ -0,0 +1,196 @@ +use crate::mappings::Mappings; +use crate::{backend, frontend}; +use heck::{CamelCase, SnakeCase}; +use std::collections::HashMap; + +pub fn transform_protocol( + mappings: &M, + state: frontend::State, + protocol: &backend::Protocol, +) -> frontend::Protocol { + let server_bound_packets = transform_packets( + mappings, + protocol, + &protocol.to_server, + frontend::Bound::Server, + ); + + let client_bound_packets = transform_packets( + mappings, + protocol, + &protocol.to_client, + frontend::Bound::Client, + ); + + frontend::Protocol { + state, + server_bound_packets, + client_bound_packets, + } +} + +fn transform_packets( + mappings: &M, + protocol: &backend::Protocol, + packets: &backend::Packets, + bound: frontend::Bound, +) -> Vec { + let packet_ids = get_packet_ids(packets); + let mut output_packets = vec![]; + + for (unformatted_name, data_vec) in packets.types.iter() { + if !unformatted_name.starts_with("packet_") + || unformatted_name == "packet_legacy_server_list_ping" + { + continue; + } + + let no_prefix_unformatted = unformatted_name.trim_start_matches("packet_"); + + let id = *packet_ids + .get(no_prefix_unformatted) + .expect("Failed to get packet id"); + + let packet_name = mappings.rename_packet( + unformatted_name, + &no_prefix_unformatted.to_camel_case(), + &bound, + protocol, + ); + + let mut fields = vec![]; + + for data in data_vec { + if let backend::Data::Container(container_vec) = data { + for container in container_vec { + match container { + backend::Container::Value { name, data } => { + match transform_field(&name, &data) { + Some(field) => { + fields.push(mappings.change_field_type(&packet_name, field)) + } + None => println!( + "[{}] Field \"{}\" are skipped ({:?}", + packet_name, name, data + ), + } + } + backend::Container::List { name, data_vec } => { + if let Some(name) = name { + for data in data_vec { + match transform_field(&name, &data) { + Some(field) => fields + .push(mappings.change_field_type(&packet_name, field)), + None => println!( + "[{}] Field \"{}\" are skipped ({:?})", + packet_name, name, data_vec + ), + } + } + } + } + } + } + } + } + + let packet = frontend::Packet { + id, + name: packet_name, + fields, + }; + + output_packets.push(packet); + } + + output_packets +} + +fn get_packet_ids(packets: &backend::Packets) -> HashMap { + let reversed_packet_ids = packets + .types + .get("packet") + .and_then(|d| d.get(1)) + .and_then(|d| match d { + backend::Data::Container(data) => data.get(0), + _ => None, + }) + .and_then(|c| match c { + backend::Container::List { data_vec, .. } => data_vec.get(1), + _ => None, + }) + .and_then(|d| match d { + backend::Data::Mapper { mappings, .. } => Some(mappings), + _ => None, + }) + .expect("Failed to get packet ids"); + + reversed_packet_ids + .into_iter() + .map(|(k, v)| { + ( + v.clone(), + u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), + ) + }) + .collect() +} + +fn transform_field(unformatted_field_name: &str, data: &backend::Data) -> Option { + match data { + backend::Data::Type(name) => match transform_data_type(name) { + Some(data_type) => Some(frontend::Field { + name: format_field_name(unformatted_field_name), + data_type, + }), + None => None, + }, + _ => None, + } +} + +fn transform_data_type(name: &str) -> Option { + match name { + "bool" => Some(frontend::DataType::Boolean), + "i8" => Some(frontend::DataType::Byte), + "i16" => Some(frontend::DataType::Short), + "i32" => Some(frontend::DataType::Int { var_int: false }), + "i64" => Some(frontend::DataType::Long { var_long: false }), + "u8" => Some(frontend::DataType::UnsignedByte), + "u16" => Some(frontend::DataType::UnsignedShort), + "f32" => Some(frontend::DataType::Float), + "f64" => Some(frontend::DataType::Double), + "varint" => Some(frontend::DataType::Int { var_int: true }), + "varlong" => Some(frontend::DataType::Long { var_long: true }), + "string" => Some(frontend::DataType::String { max_length: 0 }), + "nbt" | "optionalNbt" => Some(frontend::DataType::CompoundTag), + "UUID" => Some(frontend::DataType::Uuid { hyphenated: false }), + "buffer" => Some(frontend::DataType::ByteArray { rest: false }), + "restBuffer" => Some(frontend::DataType::ByteArray { rest: true }), + "position" => Some(frontend::DataType::RefType { + ref_name: "Position".to_string(), + }), + "slot" => Some(frontend::DataType::RefType { + ref_name: "Option".to_string(), + }), + "entityMetadata" => Some(frontend::DataType::RefType { + ref_name: "Metadata".to_string(), + }), + "tags" => Some(frontend::DataType::RefType { + ref_name: "TagsMap".to_string(), + }), + "option" => None, + _ => { + println!("Unknown data type \"{}\"", name); + None + } + } +} + +fn format_field_name(unformatted_field_name: &str) -> String { + if unformatted_field_name == "type" { + String::from("type_") + } else { + unformatted_field_name.to_snake_case() + } +} diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs index 95e2fcb..cf94310 100644 --- a/protocol/src/data/game.rs +++ b/protocol/src/data/game.rs @@ -1,6 +1,4 @@ -use crate::error::{DecodeError, EncodeError}; -use crate::{impl_enum_encoder_decoder, Decoder, DecoderReadExt, Encoder, EncoderWriteExt}; -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use crate::impl_enum_encoder_decoder; use nbt::CompoundTag; use num_derive::{FromPrimitive, ToPrimitive}; use std::io::{Read, Write}; @@ -32,31 +30,6 @@ pub struct Position { pub z: i32, } -impl Encoder for Position { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - let encoded_x = (self.x & 0x3FFFFFF) as i64; - let encoded_y = (self.y & 0xFFF) as i64; - let encoded_z = (self.z & 0x3FFFFFF) as i64; - - writer.write_i64::((encoded_x << 38) | (encoded_z << 12) | encoded_y)?; - Ok(()) - } -} - -impl Decoder for Position { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - let encoded = reader.read_i64::()?; - - let x = (encoded >> 38) as i32; - let y = (encoded & 0xFFF) as i16; - let z = (encoded << 26 >> 38) as i32; - - Ok(Position { x, y, z }) - } -} - #[derive(Debug)] pub struct Slot { pub id: i32, @@ -64,86 +37,8 @@ pub struct Slot { pub compound_tag: CompoundTag, } -impl Encoder for Option { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - match self { - Some(slot) => { - writer.write_bool(true)?; - slot.encode(writer) - } - None => writer.write_bool(false), - } - } -} - -impl Decoder for Option { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - if reader.read_bool()? { - Ok(Some(Slot::decode(reader)?)) - } else { - Ok(None) - } - } -} - -impl Encoder for Slot { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - writer.write_var_i32(self.id)?; - writer.write_u8(self.amount)?; - writer.write_compound_tag(&self.compound_tag)?; - - Ok(()) - } -} - -impl Decoder for Slot { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - let id = reader.read_var_i32()?; - let amount = reader.read_u8()?; - let compound_tag = reader.read_compound_tag()?; - - Ok(Slot { - id, - amount, - compound_tag, - }) - } -} - #[derive(Debug)] pub struct Metadata {} -impl Encoder for Metadata { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - unimplemented!() - } -} - -impl Decoder for Metadata { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - unimplemented!() - } -} - #[derive(Debug)] pub struct TagsMap {} - -impl Encoder for TagsMap { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - unimplemented!() - } -} - -impl Decoder for TagsMap { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - unimplemented!() - } -} diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index fdcbbc2..cb858c1 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -10,6 +10,7 @@ use uuid::Uuid; use data::chat::Message; +use crate::data::game::{Metadata, Position, Slot, TagsMap}; use crate::error::{DecodeError, EncodeError}; pub mod data; @@ -509,6 +510,109 @@ macro_rules! impl_json_encoder_decoder ( ); ); +impl Encoder for Position { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + let encoded_x = (self.x & 0x3FFFFFF) as i64; + let encoded_y = (self.y & 0xFFF) as i64; + let encoded_z = (self.z & 0x3FFFFFF) as i64; + + writer.write_i64::((encoded_x << 38) | (encoded_z << 12) | encoded_y)?; + Ok(()) + } +} + +impl Decoder for Position { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + let encoded = reader.read_i64::()?; + + let x = (encoded >> 38) as i32; + let y = (encoded & 0xFFF) as i16; + let z = (encoded << 26 >> 38) as i32; + + Ok(Position { x, y, z }) + } +} + +impl Encoder for Option { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + match self { + Some(slot) => { + writer.write_bool(true)?; + slot.encode(writer) + } + None => writer.write_bool(false), + } + } +} + +impl Decoder for Option { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + if reader.read_bool()? { + Ok(Some(Slot::decode(reader)?)) + } else { + Ok(None) + } + } +} + +impl Encoder for Slot { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + writer.write_var_i32(self.id)?; + writer.write_u8(self.amount)?; + writer.write_compound_tag(&self.compound_tag)?; + + Ok(()) + } +} + +impl Decoder for Slot { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + let id = reader.read_var_i32()?; + let amount = reader.read_u8()?; + let compound_tag = reader.read_compound_tag()?; + + Ok(Slot { + id, + amount, + compound_tag, + }) + } +} + +impl Encoder for Metadata { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for Metadata { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} + +impl Encoder for TagsMap { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for TagsMap { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} + mod var_int { use std::io::{Read, Write}; From e8a061e672ae4a93aede939d2cb7b4d6f300f57b Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Mon, 8 Feb 2021 23:37:10 +0300 Subject: [PATCH 18/22] Refactor --- protocol-generator/src/{data/output.rs => frontend.rs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename protocol-generator/src/{data/output.rs => frontend.rs} (99%) diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/frontend.rs similarity index 99% rename from protocol-generator/src/data/output.rs rename to protocol-generator/src/frontend.rs index 91c0ece..dda1d30 100644 --- a/protocol-generator/src/data/output.rs +++ b/protocol-generator/src/frontend.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use std::fmt; use std::fmt::Display; -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum State { Handshake, Status, From c6d1cdecc7565ae200056c2aae1cf48489e07c03 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Tue, 9 Feb 2021 03:04:40 +0300 Subject: [PATCH 19/22] Refactor --- protocol-generator/src/frontend.rs | 49 ++++++ protocol-generator/src/main.rs | 149 +++--------------- protocol-generator/src/templates.rs | 73 +++++++++ .../src/{transformer.rs => transformers.rs} | 0 4 files changed, 142 insertions(+), 129 deletions(-) create mode 100644 protocol-generator/src/templates.rs rename protocol-generator/src/{transformer.rs => transformers.rs} (100%) diff --git a/protocol-generator/src/frontend.rs b/protocol-generator/src/frontend.rs index dda1d30..49ce8f1 100644 --- a/protocol-generator/src/frontend.rs +++ b/protocol-generator/src/frontend.rs @@ -1,7 +1,11 @@ +use crate::frontend; +use handlebars::{Handlebars, TemplateRenderError}; use serde::Serialize; +use serde_json::json; use std::collections::HashSet; use std::fmt; use std::fmt::Display; +use std::io::Write; #[derive(Debug, Copy, Clone)] pub enum State { @@ -172,3 +176,48 @@ impl Protocol { .collect() } } + +#[derive(Serialize)] +struct GenerateContext<'a> { + packet_enum_name: String, + packets: &'a Vec, +} + +pub fn generate_rust_file( + protocol: &frontend::Protocol, + template_engine: &Handlebars, + mut writer: W, +) -> Result<(), TemplateRenderError> { + let server_bound_ctx = GenerateContext { + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server), + packets: &protocol.server_bound_packets, + }; + + let client_bound_ctx = GenerateContext { + packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client), + packets: &protocol.client_bound_packets, + }; + + let mut imports = vec![ + "crate::DecodeError", + "crate::Decoder", + "std::io::Read", + "minecraft_protocol_derive::Packet", + ]; + + imports.extend(protocol.data_type_imports().iter()); + + template_engine.render_to_write( + "packet_imports", + &json!({ "imports": imports }), + &mut writer, + )?; + + template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?; + + template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?; + template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?; + + Ok(()) +} diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index ffbd346..cd6f1cc 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -1,18 +1,13 @@ use std::fs::File; -use std::io::Write; use crate::mappings::CodeMappings; -use crate::transformer::transform_protocol; -use handlebars::*; -use heck::SnakeCase; -use serde::Serialize; -use serde_json::json; use structopt::StructOpt; pub mod backend; pub mod frontend; pub mod mappings; -pub mod transformer; +pub mod templates; +pub mod transformers; #[derive(StructOpt)] #[structopt(name = "protocol-generator")] @@ -23,7 +18,7 @@ struct Opt { pub fn main() { let opt: Opt = Opt::from_args(); - let template_engine = create_template_engine(); + let template_engine = templates::create_template_engine(); let protocol_data_file_name = format!( "protocol-generator/minecraft-data/data/pc/{}/protocol.json", @@ -40,7 +35,7 @@ pub fn main() { let protocols = vec![ ( - transform_protocol( + transformers::transform_protocol( &mappings, frontend::State::Handshake, &protocol_input.handshaking, @@ -48,15 +43,27 @@ pub fn main() { frontend::State::Handshake, ), ( - transform_protocol(&mappings, frontend::State::Status, &protocol_input.status), + transformers::transform_protocol( + &mappings, + frontend::State::Status, + &protocol_input.status, + ), frontend::State::Status, ), ( - transform_protocol(&mappings, frontend::State::Login, &protocol_input.login), + transformers::transform_protocol( + &mappings, + frontend::State::Login, + &protocol_input.login, + ), frontend::State::Login, ), ( - transform_protocol(&mappings, frontend::State::Game, &protocol_input.game), + transformers::transform_protocol( + &mappings, + frontend::State::Game, + &protocol_input.game, + ), frontend::State::Game, ), ]; @@ -68,123 +75,7 @@ pub fn main() { ); let file = File::create(file_name).expect("Failed to create file"); - generate_rust_file(&protocol, &template_engine, &file) + frontend::generate_rust_file(&protocol, &template_engine, &file) .expect("Failed to generate rust file"); } } - -fn create_template_engine() -> Handlebars<'static> { - let mut template_engine = Handlebars::new(); - - template_engine.register_helper("snake_case", Box::new(format_snake_case)); - template_engine.register_helper("packet_id", Box::new(format_packet_id)); - template_engine.register_escape_fn(|s| s.to_owned()); - - template_engine - .register_template_file( - "packet_imports", - "protocol-generator/templates/packet_imports.hbs", - ) - .expect("Failed to register template"); - - template_engine - .register_template_file( - "packet_enum", - "protocol-generator/templates/packet_enum.hbs", - ) - .expect("Failed to register template"); - - template_engine - .register_template_file( - "packet_structs", - "protocol-generator/templates/packet_structs.hbs", - ) - .expect("Failed to register template"); - - template_engine -} - -#[derive(Serialize)] -struct GenerateContext<'a> { - packet_enum_name: String, - packets: &'a Vec, -} - -fn generate_rust_file( - protocol: &frontend::Protocol, - template_engine: &Handlebars, - mut writer: W, -) -> Result<(), TemplateRenderError> { - let server_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server), - packets: &protocol.server_bound_packets, - }; - - let client_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client), - packets: &protocol.client_bound_packets, - }; - - let mut imports = vec![ - "crate::DecodeError", - "crate::Decoder", - "std::io::Read", - "minecraft_protocol_derive::Packet", - ]; - - imports.extend(protocol.data_type_imports().iter()); - - template_engine.render_to_write( - "packet_imports", - &json!({ "imports": imports }), - &mut writer, - )?; - - template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?; - - template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?; - - Ok(()) -} - -fn format_snake_case( - h: &Helper, - _: &Handlebars, - _: &Context, - _: &mut RenderContext, - out: &mut dyn Output, -) -> Result<(), RenderError> { - let str = h - .param(0) - .and_then(|v| v.value().as_str()) - .ok_or(RenderError::new( - "Param 0 with str type is required for snake case helper.", - ))? as &str; - - let snake_case_str = str.to_snake_case(); - - out.write(snake_case_str.as_ref())?; - Ok(()) -} - -fn format_packet_id( - h: &Helper, - _: &Handlebars, - _: &Context, - _: &mut RenderContext, - out: &mut dyn Output, -) -> Result<(), RenderError> { - let id = h - .param(0) - .and_then(|v| v.value().as_u64()) - .ok_or(RenderError::new( - "Param 0 with u64 type is required for packet id helper.", - ))? as u64; - - let packet_id_str = format!("{:#04X}", id); - - out.write(packet_id_str.as_ref())?; - Ok(()) -} diff --git a/protocol-generator/src/templates.rs b/protocol-generator/src/templates.rs new file mode 100644 index 0000000..2bc1993 --- /dev/null +++ b/protocol-generator/src/templates.rs @@ -0,0 +1,73 @@ +use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError}; +use heck::SnakeCase; + +pub fn create_template_engine() -> Handlebars<'static> { + let mut template_engine = Handlebars::new(); + + template_engine.register_helper("snake_case", Box::new(format_snake_case)); + template_engine.register_helper("packet_id", Box::new(format_packet_id)); + template_engine.register_escape_fn(|s| s.to_owned()); + + template_engine + .register_template_file( + "packet_imports", + "protocol-generator/templates/packet_imports.hbs", + ) + .expect("Failed to register template"); + + template_engine + .register_template_file( + "packet_enum", + "protocol-generator/templates/packet_enum.hbs", + ) + .expect("Failed to register template"); + + template_engine + .register_template_file( + "packet_structs", + "protocol-generator/templates/packet_structs.hbs", + ) + .expect("Failed to register template"); + + template_engine +} + +fn format_snake_case( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output, +) -> Result<(), RenderError> { + let str = h + .param(0) + .and_then(|v| v.value().as_str()) + .ok_or(RenderError::new( + "Param 0 with str type is required for snake case helper.", + ))? as &str; + + let snake_case_str = str.to_snake_case(); + + out.write(snake_case_str.as_ref())?; + Ok(()) +} + +fn format_packet_id( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output, +) -> Result<(), RenderError> { + let id = h + .param(0) + .and_then(|v| v.value().as_u64()) + .ok_or(RenderError::new( + "Param 0 with u64 type is required for packet id helper.", + ))? as u64; + + let packet_id_str = format!("{:#04X}", id); + + out.write(packet_id_str.as_ref())?; + Ok(()) +} diff --git a/protocol-generator/src/transformer.rs b/protocol-generator/src/transformers.rs similarity index 100% rename from protocol-generator/src/transformer.rs rename to protocol-generator/src/transformers.rs From 2d9b9dd94f96a4b62f0bb2ffc0310e32d205a817 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Tue, 9 Feb 2021 03:14:55 +0300 Subject: [PATCH 20/22] Fix backend list parsing --- protocol-generator/src/backend.rs | 16 ++++++++-------- protocol-generator/src/main.rs | 11 ++++++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/protocol-generator/src/backend.rs b/protocol-generator/src/backend.rs index d8b3ced..316d929 100644 --- a/protocol-generator/src/backend.rs +++ b/protocol-generator/src/backend.rs @@ -55,10 +55,6 @@ pub enum Container { #[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum Switch { - Empty { - #[serde(rename = "compareTo")] - compare_to: String, - }, Value { #[serde(rename = "compareTo")] compare_to: String, @@ -69,15 +65,15 @@ pub enum Switch { compare_to: String, fields: LinkedHashMap>, }, + Empty { + #[serde(rename = "compareTo")] + compare_to: String, + }, } #[derive(Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum List { - Empty { - #[serde(rename = "countType")] - count_type: String, - }, Value { #[serde(rename = "countType")] count_type: String, @@ -90,6 +86,10 @@ pub enum List { #[serde(rename = "type")] list_type: Vec, }, + Empty { + #[serde(rename = "countType")] + count_type: String, + }, } #[derive(Debug, Deserialize, PartialEq, Eq)] diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index cd6f1cc..ecc1d61 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -28,7 +28,7 @@ pub fn main() { let protocol_data_file = File::open(protocol_data_file_name).expect("Failed to open protocol data file"); - let protocol_input: backend::ProtocolHandler = + let protocol_handler: backend::ProtocolHandler = serde_json::from_reader(protocol_data_file).expect("Failed to parse protocol data"); let mappings = CodeMappings {}; @@ -38,7 +38,7 @@ pub fn main() { transformers::transform_protocol( &mappings, frontend::State::Handshake, - &protocol_input.handshaking, + &protocol_handler.handshaking, ), frontend::State::Handshake, ), @@ -46,7 +46,7 @@ pub fn main() { transformers::transform_protocol( &mappings, frontend::State::Status, - &protocol_input.status, + &protocol_handler.status, ), frontend::State::Status, ), @@ -54,7 +54,7 @@ pub fn main() { transformers::transform_protocol( &mappings, frontend::State::Login, - &protocol_input.login, + &protocol_handler.login, ), frontend::State::Login, ), @@ -62,7 +62,7 @@ pub fn main() { transformers::transform_protocol( &mappings, frontend::State::Game, - &protocol_input.game, + &protocol_handler.game, ), frontend::State::Game, ), @@ -73,6 +73,7 @@ pub fn main() { "protocol/src/packet/{}.rs", state.to_string().to_lowercase() ); + let file = File::create(file_name).expect("Failed to create file"); frontend::generate_rust_file(&protocol, &template_engine, &file) From b043dbb07be8da0c4da0777760cc2ebc885c2705 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Tue, 9 Feb 2021 13:05:08 +0300 Subject: [PATCH 21/22] WIP list field --- protocol-generator/src/transformers.rs | 107 +++++++++++++++---------- protocol/src/data/game.rs | 3 + protocol/src/lib.rs | 16 +++- protocol/src/packet/game.rs | 3 + 4 files changed, 86 insertions(+), 43 deletions(-) diff --git a/protocol-generator/src/transformers.rs b/protocol-generator/src/transformers.rs index 20cb518..155bb8e 100644 --- a/protocol-generator/src/transformers.rs +++ b/protocol-generator/src/transformers.rs @@ -1,3 +1,4 @@ +use crate::backend::Data; use crate::mappings::Mappings; use crate::{backend, frontend}; use heck::{CamelCase, SnakeCase}; @@ -29,6 +30,36 @@ pub fn transform_protocol( } } +fn get_packet_ids(packets: &backend::Packets) -> HashMap { + let reversed_packet_ids = packets + .types + .get("packet") + .and_then(|d| d.get(1)) + .and_then(|d| match d { + backend::Data::Container(data) => data.get(0), + _ => None, + }) + .and_then(|c| match c { + backend::Container::List { data_vec, .. } => data_vec.get(1), + _ => None, + }) + .and_then(|d| match d { + backend::Data::Mapper { mappings, .. } => Some(mappings), + _ => None, + }) + .expect("Failed to get packet ids"); + + reversed_packet_ids + .into_iter() + .map(|(k, v)| { + ( + v.clone(), + u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), + ) + }) + .collect() +} + fn transform_packets( mappings: &M, protocol: &backend::Protocol, @@ -65,7 +96,7 @@ fn transform_packets( for container in container_vec { match container { backend::Container::Value { name, data } => { - match transform_field(&name, &data) { + match transform_value_field(&name, &data) { Some(field) => { fields.push(mappings.change_field_type(&packet_name, field)) } @@ -77,15 +108,11 @@ fn transform_packets( } backend::Container::List { name, data_vec } => { if let Some(name) = name { - for data in data_vec { - match transform_field(&name, &data) { - Some(field) => fields - .push(mappings.change_field_type(&packet_name, field)), - None => println!( - "[{}] Field \"{}\" are skipped ({:?})", - packet_name, name, data_vec - ), + match transform_list_field(&name, data_vec) { + Some(field) => { + fields.push(mappings.change_field_type(&packet_name, field)) } + None => {} } } } @@ -106,37 +133,10 @@ fn transform_packets( output_packets } -fn get_packet_ids(packets: &backend::Packets) -> HashMap { - let reversed_packet_ids = packets - .types - .get("packet") - .and_then(|d| d.get(1)) - .and_then(|d| match d { - backend::Data::Container(data) => data.get(0), - _ => None, - }) - .and_then(|c| match c { - backend::Container::List { data_vec, .. } => data_vec.get(1), - _ => None, - }) - .and_then(|d| match d { - backend::Data::Mapper { mappings, .. } => Some(mappings), - _ => None, - }) - .expect("Failed to get packet ids"); - - reversed_packet_ids - .into_iter() - .map(|(k, v)| { - ( - v.clone(), - u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), - ) - }) - .collect() -} - -fn transform_field(unformatted_field_name: &str, data: &backend::Data) -> Option { +fn transform_value_field( + unformatted_field_name: &str, + data: &backend::Data, +) -> Option { match data { backend::Data::Type(name) => match transform_data_type(name) { Some(data_type) => Some(frontend::Field { @@ -149,6 +149,31 @@ fn transform_field(unformatted_field_name: &str, data: &backend::Data) -> Option } } +fn transform_list_field( + unformatted_field_name: &str, + data_vec: &Vec, +) -> Option { + match &data_vec[0] { + backend::Data::Type(name) => match name.as_ref() { + "buffer" => Some(frontend::Field { + name: format_field_name(unformatted_field_name), + data_type: frontend::DataType::ByteArray { rest: false }, + }), + "array" => None, + "switch" => None, + "particleData" => Some(frontend::Field { + name: format_field_name(unformatted_field_name), + data_type: frontend::DataType::RefType { + ref_name: "ParticleData".to_string(), + }, + }), + "option" => transform_value_field(unformatted_field_name, &data_vec[1]), + _ => None, + }, + _ => None, + } +} + fn transform_data_type(name: &str) -> Option { match name { "bool" => Some(frontend::DataType::Boolean), @@ -165,7 +190,6 @@ fn transform_data_type(name: &str) -> Option { "string" => Some(frontend::DataType::String { max_length: 0 }), "nbt" | "optionalNbt" => Some(frontend::DataType::CompoundTag), "UUID" => Some(frontend::DataType::Uuid { hyphenated: false }), - "buffer" => Some(frontend::DataType::ByteArray { rest: false }), "restBuffer" => Some(frontend::DataType::ByteArray { rest: true }), "position" => Some(frontend::DataType::RefType { ref_name: "Position".to_string(), @@ -179,7 +203,6 @@ fn transform_data_type(name: &str) -> Option { "tags" => Some(frontend::DataType::RefType { ref_name: "TagsMap".to_string(), }), - "option" => None, _ => { println!("Unknown data type \"{}\"", name); None diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs index cf94310..fdc6860 100644 --- a/protocol/src/data/game.rs +++ b/protocol/src/data/game.rs @@ -42,3 +42,6 @@ pub struct Metadata {} #[derive(Debug)] pub struct TagsMap {} + +#[derive(Debug)] +pub struct ParticleData {} diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index cb858c1..9c3adbd 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -10,7 +10,7 @@ use uuid::Uuid; use data::chat::Message; -use crate::data::game::{Metadata, Position, Slot, TagsMap}; +use crate::data::game::{Metadata, ParticleData, Position, Slot, TagsMap}; use crate::error::{DecodeError, EncodeError}; pub mod data; @@ -613,6 +613,20 @@ impl Decoder for TagsMap { } } +impl Encoder for ParticleData { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for ParticleData { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} + mod var_int { use std::io::{Read, Write}; diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs index 290aea1..cb6dc25 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/packet/game.rs @@ -1908,6 +1908,7 @@ impl GameClientBoundPacket { offset_z: f32, particle_data: f32, particles: i32, + data: ParticleData, ) -> Self { let world_particles = WorldParticles { particle_id, @@ -1920,6 +1921,7 @@ impl GameClientBoundPacket { offset_z, particle_data, particles, + data, }; Self::WorldParticles(world_particles) @@ -3157,6 +3159,7 @@ pub struct WorldParticles { pub offset_z: f32, pub particle_data: f32, pub particles: i32, + pub data: ParticleData, } #[derive(Packet, Debug)] From a121323eed26dbf4daea042b4011bb3ff13c18d7 Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Tue, 9 Feb 2021 23:36:13 +0300 Subject: [PATCH 22/22] Add multi version support --- protocol-generator/Cargo.toml | 1 - protocol-generator/minecraft-data | 2 +- protocol-generator/src/backend.rs | 3 +- protocol-generator/src/frontend.rs | 186 +- protocol-generator/src/main.rs | 111 +- protocol-generator/src/mappings.rs | 24 +- protocol-generator/src/templates.rs | 50 +- protocol-generator/src/transformers.rs | 34 +- ...packet_structs.hbs => packets_structs.hbs} | 2 +- .../{packet_enum.hbs => protocol_enum.hbs} | 10 +- .../templates/protocol_header.hbs | 10 + ...packet_imports.hbs => protocol_module.hbs} | 7 +- .../templates/protocol_versions_module.hbs | 6 + protocol/src/data/game.rs | 47 - protocol/src/data/mod.rs | 3 +- .../src/data/{status.rs => server_status.rs} | 0 protocol/src/lib.rs | 120 +- protocol/src/packet/mod.rs | 4 - protocol/src/version/mod.rs | 72 + protocol/src/version/v_15w40b/game.rs | 2555 ++++++++++++ .../{packet => version/v_15w40b}/handshake.rs | 4 +- protocol/src/version/v_15w40b/login.rs | 162 + protocol/src/version/v_15w40b/mod.rs | 6 + .../{packet => version/v_15w40b}/status.rs | 13 +- protocol/src/version/v_16w20a/game.rs | 2685 ++++++++++++ protocol/src/version/v_16w20a/handshake.rs | 55 + protocol/src/version/v_16w20a/login.rs | 162 + protocol/src/version/v_16w20a/mod.rs | 6 + protocol/src/version/v_16w20a/status.rs | 99 + protocol/src/version/v_16w35a/game.rs | 2692 ++++++++++++ protocol/src/version/v_16w35a/handshake.rs | 55 + protocol/src/version/v_16w35a/login.rs | 162 + protocol/src/version/v_16w35a/mod.rs | 6 + protocol/src/version/v_16w35a/status.rs | 99 + protocol/src/version/v_17w15a/game.rs | 2781 +++++++++++++ protocol/src/version/v_17w15a/handshake.rs | 55 + protocol/src/version/v_17w15a/login.rs | 162 + protocol/src/version/v_17w15a/mod.rs | 6 + protocol/src/version/v_17w15a/status.rs | 99 + protocol/src/version/v_17w18b/game.rs | 2778 +++++++++++++ protocol/src/version/v_17w18b/handshake.rs | 55 + protocol/src/version/v_17w18b/login.rs | 162 + protocol/src/version/v_17w18b/mod.rs | 6 + protocol/src/version/v_17w18b/status.rs | 99 + protocol/src/version/v_17w50a/game.rs | 2917 +++++++++++++ protocol/src/version/v_17w50a/handshake.rs | 55 + protocol/src/version/v_17w50a/login.rs | 162 + protocol/src/version/v_17w50a/mod.rs | 6 + protocol/src/version/v_17w50a/status.rs | 99 + protocol/src/version/v_1_10/game.rs | 2684 ++++++++++++ protocol/src/version/v_1_10/handshake.rs | 55 + protocol/src/version/v_1_10/login.rs | 162 + protocol/src/version/v_1_10/mod.rs | 6 + protocol/src/version/v_1_10/status.rs | 99 + protocol/src/version/v_1_10_pre1/game.rs | 2684 ++++++++++++ protocol/src/version/v_1_10_pre1/handshake.rs | 55 + protocol/src/version/v_1_10_pre1/login.rs | 162 + protocol/src/version/v_1_10_pre1/mod.rs | 6 + protocol/src/version/v_1_10_pre1/status.rs | 99 + protocol/src/version/v_1_11/game.rs | 2692 ++++++++++++ protocol/src/version/v_1_11/handshake.rs | 55 + protocol/src/version/v_1_11/login.rs | 162 + protocol/src/version/v_1_11/mod.rs | 6 + protocol/src/version/v_1_11/status.rs | 99 + protocol/src/version/v_1_12/game.rs | 2817 +++++++++++++ protocol/src/version/v_1_12/handshake.rs | 55 + protocol/src/version/v_1_12/login.rs | 162 + protocol/src/version/v_1_12/mod.rs | 6 + protocol/src/version/v_1_12/status.rs | 99 + protocol/src/version/v_1_12_1/game.rs | 2840 +++++++++++++ protocol/src/version/v_1_12_1/handshake.rs | 55 + protocol/src/version/v_1_12_1/login.rs | 162 + protocol/src/version/v_1_12_1/mod.rs | 6 + protocol/src/version/v_1_12_1/status.rs | 99 + protocol/src/version/v_1_12_2/game.rs | 2838 +++++++++++++ protocol/src/version/v_1_12_2/handshake.rs | 55 + protocol/src/version/v_1_12_2/login.rs | 162 + protocol/src/version/v_1_12_2/mod.rs | 6 + protocol/src/version/v_1_12_2/status.rs | 99 + protocol/src/version/v_1_12_pre4/game.rs | 2815 +++++++++++++ protocol/src/version/v_1_12_pre4/handshake.rs | 55 + protocol/src/version/v_1_12_pre4/login.rs | 162 + protocol/src/version/v_1_12_pre4/mod.rs | 6 + protocol/src/version/v_1_12_pre4/status.rs | 99 + protocol/src/version/v_1_13/game.rs | 3257 +++++++++++++++ protocol/src/version/v_1_13/handshake.rs | 55 + protocol/src/version/v_1_13/login.rs | 209 + protocol/src/version/v_1_13/mod.rs | 6 + protocol/src/version/v_1_13/status.rs | 99 + protocol/src/version/v_1_13_1/game.rs | 3263 +++++++++++++++ protocol/src/version/v_1_13_1/handshake.rs | 55 + protocol/src/version/v_1_13_1/login.rs | 209 + protocol/src/version/v_1_13_1/mod.rs | 6 + protocol/src/version/v_1_13_1/status.rs | 99 + protocol/src/version/v_1_13_2/game.rs | 3263 +++++++++++++++ protocol/src/version/v_1_13_2/handshake.rs | 55 + protocol/src/version/v_1_13_2/login.rs | 209 + protocol/src/version/v_1_13_2/mod.rs | 6 + protocol/src/version/v_1_13_2/status.rs | 99 + protocol/src/version/v_1_13_2_pre1/game.rs | 3263 +++++++++++++++ .../src/version/v_1_13_2_pre1/handshake.rs | 55 + protocol/src/version/v_1_13_2_pre1/login.rs | 209 + protocol/src/version/v_1_13_2_pre1/mod.rs | 6 + protocol/src/version/v_1_13_2_pre1/status.rs | 99 + protocol/src/version/v_1_13_2_pre2/game.rs | 3263 +++++++++++++++ .../src/version/v_1_13_2_pre2/handshake.rs | 55 + protocol/src/version/v_1_13_2_pre2/login.rs | 209 + protocol/src/version/v_1_13_2_pre2/mod.rs | 6 + protocol/src/version/v_1_13_2_pre2/status.rs | 99 + protocol/src/version/v_1_14/game.rs | 3535 ++++++++++++++++ protocol/src/version/v_1_14/handshake.rs | 55 + protocol/src/version/v_1_14/login.rs | 209 + protocol/src/version/v_1_14/mod.rs | 6 + protocol/src/version/v_1_14/status.rs | 99 + protocol/src/version/v_1_14_1/game.rs | 3535 ++++++++++++++++ protocol/src/version/v_1_14_1/handshake.rs | 55 + protocol/src/version/v_1_14_1/login.rs | 209 + protocol/src/version/v_1_14_1/mod.rs | 6 + protocol/src/version/v_1_14_1/status.rs | 99 + protocol/src/version/v_1_14_3/game.rs | 3538 ++++++++++++++++ protocol/src/version/v_1_14_3/handshake.rs | 55 + protocol/src/version/v_1_14_3/login.rs | 209 + protocol/src/version/v_1_14_3/mod.rs | 6 + protocol/src/version/v_1_14_3/status.rs | 99 + .../src/{packet => version/v_1_14_4}/game.rs | 20 +- protocol/src/version/v_1_14_4/handshake.rs | 55 + protocol/src/version/v_1_14_4/login.rs | 209 + protocol/src/version/v_1_14_4/mod.rs | 6 + protocol/src/version/v_1_14_4/status.rs | 99 + protocol/src/version/v_1_15/game.rs | 3573 ++++++++++++++++ protocol/src/version/v_1_15/handshake.rs | 55 + protocol/src/version/v_1_15/login.rs | 209 + protocol/src/version/v_1_15/mod.rs | 6 + protocol/src/version/v_1_15/status.rs | 99 + protocol/src/version/v_1_15_1/game.rs | 3573 ++++++++++++++++ protocol/src/version/v_1_15_1/handshake.rs | 55 + protocol/src/version/v_1_15_1/login.rs | 209 + protocol/src/version/v_1_15_1/mod.rs | 6 + protocol/src/version/v_1_15_1/status.rs | 99 + protocol/src/version/v_1_15_2/game.rs | 3573 ++++++++++++++++ protocol/src/version/v_1_15_2/handshake.rs | 55 + protocol/src/version/v_1_15_2/login.rs | 209 + protocol/src/version/v_1_15_2/mod.rs | 6 + protocol/src/version/v_1_15_2/status.rs | 99 + protocol/src/version/v_1_16/game.rs | 3607 ++++++++++++++++ protocol/src/version/v_1_16/handshake.rs | 55 + .../src/{packet => version/v_1_16}/login.rs | 15 +- protocol/src/version/v_1_16/mod.rs | 6 + protocol/src/version/v_1_16/status.rs | 99 + protocol/src/version/v_1_16_1/game.rs | 3607 ++++++++++++++++ protocol/src/version/v_1_16_1/handshake.rs | 55 + protocol/src/version/v_1_16_1/login.rs | 211 + protocol/src/version/v_1_16_1/mod.rs | 6 + protocol/src/version/v_1_16_1/status.rs | 99 + protocol/src/version/v_1_16_2/game.rs | 3643 +++++++++++++++++ protocol/src/version/v_1_16_2/handshake.rs | 55 + protocol/src/version/v_1_16_2/login.rs | 211 + protocol/src/version/v_1_16_2/mod.rs | 6 + protocol/src/version/v_1_16_2/status.rs | 99 + protocol/src/version/v_1_16_rc1/game.rs | 3607 ++++++++++++++++ protocol/src/version/v_1_16_rc1/handshake.rs | 55 + protocol/src/version/v_1_16_rc1/login.rs | 211 + protocol/src/version/v_1_16_rc1/mod.rs | 6 + protocol/src/version/v_1_16_rc1/status.rs | 99 + protocol/src/version/v_1_8/game.rs | 2475 +++++++++++ protocol/src/version/v_1_8/handshake.rs | 55 + protocol/src/version/v_1_8/login.rs | 162 + protocol/src/version/v_1_8/mod.rs | 6 + protocol/src/version/v_1_8/status.rs | 99 + protocol/src/version/v_1_9/game.rs | 2719 ++++++++++++ protocol/src/version/v_1_9/handshake.rs | 55 + protocol/src/version/v_1_9/login.rs | 162 + protocol/src/version/v_1_9/mod.rs | 6 + protocol/src/version/v_1_9/status.rs | 99 + protocol/src/version/v_1_9_1_pre2/game.rs | 2719 ++++++++++++ .../src/version/v_1_9_1_pre2/handshake.rs | 55 + protocol/src/version/v_1_9_1_pre2/login.rs | 162 + protocol/src/version/v_1_9_1_pre2/mod.rs | 6 + protocol/src/version/v_1_9_1_pre2/status.rs | 99 + protocol/src/version/v_1_9_2/game.rs | 2719 ++++++++++++ protocol/src/version/v_1_9_2/handshake.rs | 55 + protocol/src/version/v_1_9_2/login.rs | 162 + protocol/src/version/v_1_9_2/mod.rs | 6 + protocol/src/version/v_1_9_2/status.rs | 99 + protocol/src/version/v_1_9_4/game.rs | 2685 ++++++++++++ protocol/src/version/v_1_9_4/handshake.rs | 55 + protocol/src/version/v_1_9_4/login.rs | 162 + protocol/src/version/v_1_9_4/mod.rs | 6 + protocol/src/version/v_1_9_4/status.rs | 99 + protocol/src/version/v_20w13b/game.rs | 3579 ++++++++++++++++ protocol/src/version/v_20w13b/handshake.rs | 55 + protocol/src/version/v_20w13b/login.rs | 211 + protocol/src/version/v_20w13b/mod.rs | 6 + protocol/src/version/v_20w13b/status.rs | 99 + 194 files changed, 116871 insertions(+), 361 deletions(-) rename protocol-generator/templates/{packet_structs.hbs => packets_structs.hbs} (98%) rename protocol-generator/templates/{packet_enum.hbs => protocol_enum.hbs} (85%) create mode 100644 protocol-generator/templates/protocol_header.hbs rename protocol-generator/templates/{packet_imports.hbs => protocol_module.hbs} (56%) create mode 100644 protocol-generator/templates/protocol_versions_module.hbs delete mode 100644 protocol/src/data/game.rs rename protocol/src/data/{status.rs => server_status.rs} (100%) delete mode 100644 protocol/src/packet/mod.rs create mode 100644 protocol/src/version/mod.rs create mode 100644 protocol/src/version/v_15w40b/game.rs rename protocol/src/{packet => version/v_15w40b}/handshake.rs (94%) create mode 100644 protocol/src/version/v_15w40b/login.rs create mode 100644 protocol/src/version/v_15w40b/mod.rs rename protocol/src/{packet => version/v_15w40b}/status.rs (89%) create mode 100644 protocol/src/version/v_16w20a/game.rs create mode 100644 protocol/src/version/v_16w20a/handshake.rs create mode 100644 protocol/src/version/v_16w20a/login.rs create mode 100644 protocol/src/version/v_16w20a/mod.rs create mode 100644 protocol/src/version/v_16w20a/status.rs create mode 100644 protocol/src/version/v_16w35a/game.rs create mode 100644 protocol/src/version/v_16w35a/handshake.rs create mode 100644 protocol/src/version/v_16w35a/login.rs create mode 100644 protocol/src/version/v_16w35a/mod.rs create mode 100644 protocol/src/version/v_16w35a/status.rs create mode 100644 protocol/src/version/v_17w15a/game.rs create mode 100644 protocol/src/version/v_17w15a/handshake.rs create mode 100644 protocol/src/version/v_17w15a/login.rs create mode 100644 protocol/src/version/v_17w15a/mod.rs create mode 100644 protocol/src/version/v_17w15a/status.rs create mode 100644 protocol/src/version/v_17w18b/game.rs create mode 100644 protocol/src/version/v_17w18b/handshake.rs create mode 100644 protocol/src/version/v_17w18b/login.rs create mode 100644 protocol/src/version/v_17w18b/mod.rs create mode 100644 protocol/src/version/v_17w18b/status.rs create mode 100644 protocol/src/version/v_17w50a/game.rs create mode 100644 protocol/src/version/v_17w50a/handshake.rs create mode 100644 protocol/src/version/v_17w50a/login.rs create mode 100644 protocol/src/version/v_17w50a/mod.rs create mode 100644 protocol/src/version/v_17w50a/status.rs create mode 100644 protocol/src/version/v_1_10/game.rs create mode 100644 protocol/src/version/v_1_10/handshake.rs create mode 100644 protocol/src/version/v_1_10/login.rs create mode 100644 protocol/src/version/v_1_10/mod.rs create mode 100644 protocol/src/version/v_1_10/status.rs create mode 100644 protocol/src/version/v_1_10_pre1/game.rs create mode 100644 protocol/src/version/v_1_10_pre1/handshake.rs create mode 100644 protocol/src/version/v_1_10_pre1/login.rs create mode 100644 protocol/src/version/v_1_10_pre1/mod.rs create mode 100644 protocol/src/version/v_1_10_pre1/status.rs create mode 100644 protocol/src/version/v_1_11/game.rs create mode 100644 protocol/src/version/v_1_11/handshake.rs create mode 100644 protocol/src/version/v_1_11/login.rs create mode 100644 protocol/src/version/v_1_11/mod.rs create mode 100644 protocol/src/version/v_1_11/status.rs create mode 100644 protocol/src/version/v_1_12/game.rs create mode 100644 protocol/src/version/v_1_12/handshake.rs create mode 100644 protocol/src/version/v_1_12/login.rs create mode 100644 protocol/src/version/v_1_12/mod.rs create mode 100644 protocol/src/version/v_1_12/status.rs create mode 100644 protocol/src/version/v_1_12_1/game.rs create mode 100644 protocol/src/version/v_1_12_1/handshake.rs create mode 100644 protocol/src/version/v_1_12_1/login.rs create mode 100644 protocol/src/version/v_1_12_1/mod.rs create mode 100644 protocol/src/version/v_1_12_1/status.rs create mode 100644 protocol/src/version/v_1_12_2/game.rs create mode 100644 protocol/src/version/v_1_12_2/handshake.rs create mode 100644 protocol/src/version/v_1_12_2/login.rs create mode 100644 protocol/src/version/v_1_12_2/mod.rs create mode 100644 protocol/src/version/v_1_12_2/status.rs create mode 100644 protocol/src/version/v_1_12_pre4/game.rs create mode 100644 protocol/src/version/v_1_12_pre4/handshake.rs create mode 100644 protocol/src/version/v_1_12_pre4/login.rs create mode 100644 protocol/src/version/v_1_12_pre4/mod.rs create mode 100644 protocol/src/version/v_1_12_pre4/status.rs create mode 100644 protocol/src/version/v_1_13/game.rs create mode 100644 protocol/src/version/v_1_13/handshake.rs create mode 100644 protocol/src/version/v_1_13/login.rs create mode 100644 protocol/src/version/v_1_13/mod.rs create mode 100644 protocol/src/version/v_1_13/status.rs create mode 100644 protocol/src/version/v_1_13_1/game.rs create mode 100644 protocol/src/version/v_1_13_1/handshake.rs create mode 100644 protocol/src/version/v_1_13_1/login.rs create mode 100644 protocol/src/version/v_1_13_1/mod.rs create mode 100644 protocol/src/version/v_1_13_1/status.rs create mode 100644 protocol/src/version/v_1_13_2/game.rs create mode 100644 protocol/src/version/v_1_13_2/handshake.rs create mode 100644 protocol/src/version/v_1_13_2/login.rs create mode 100644 protocol/src/version/v_1_13_2/mod.rs create mode 100644 protocol/src/version/v_1_13_2/status.rs create mode 100644 protocol/src/version/v_1_13_2_pre1/game.rs create mode 100644 protocol/src/version/v_1_13_2_pre1/handshake.rs create mode 100644 protocol/src/version/v_1_13_2_pre1/login.rs create mode 100644 protocol/src/version/v_1_13_2_pre1/mod.rs create mode 100644 protocol/src/version/v_1_13_2_pre1/status.rs create mode 100644 protocol/src/version/v_1_13_2_pre2/game.rs create mode 100644 protocol/src/version/v_1_13_2_pre2/handshake.rs create mode 100644 protocol/src/version/v_1_13_2_pre2/login.rs create mode 100644 protocol/src/version/v_1_13_2_pre2/mod.rs create mode 100644 protocol/src/version/v_1_13_2_pre2/status.rs create mode 100644 protocol/src/version/v_1_14/game.rs create mode 100644 protocol/src/version/v_1_14/handshake.rs create mode 100644 protocol/src/version/v_1_14/login.rs create mode 100644 protocol/src/version/v_1_14/mod.rs create mode 100644 protocol/src/version/v_1_14/status.rs create mode 100644 protocol/src/version/v_1_14_1/game.rs create mode 100644 protocol/src/version/v_1_14_1/handshake.rs create mode 100644 protocol/src/version/v_1_14_1/login.rs create mode 100644 protocol/src/version/v_1_14_1/mod.rs create mode 100644 protocol/src/version/v_1_14_1/status.rs create mode 100644 protocol/src/version/v_1_14_3/game.rs create mode 100644 protocol/src/version/v_1_14_3/handshake.rs create mode 100644 protocol/src/version/v_1_14_3/login.rs create mode 100644 protocol/src/version/v_1_14_3/mod.rs create mode 100644 protocol/src/version/v_1_14_3/status.rs rename protocol/src/{packet => version/v_1_14_4}/game.rs (99%) create mode 100644 protocol/src/version/v_1_14_4/handshake.rs create mode 100644 protocol/src/version/v_1_14_4/login.rs create mode 100644 protocol/src/version/v_1_14_4/mod.rs create mode 100644 protocol/src/version/v_1_14_4/status.rs create mode 100644 protocol/src/version/v_1_15/game.rs create mode 100644 protocol/src/version/v_1_15/handshake.rs create mode 100644 protocol/src/version/v_1_15/login.rs create mode 100644 protocol/src/version/v_1_15/mod.rs create mode 100644 protocol/src/version/v_1_15/status.rs create mode 100644 protocol/src/version/v_1_15_1/game.rs create mode 100644 protocol/src/version/v_1_15_1/handshake.rs create mode 100644 protocol/src/version/v_1_15_1/login.rs create mode 100644 protocol/src/version/v_1_15_1/mod.rs create mode 100644 protocol/src/version/v_1_15_1/status.rs create mode 100644 protocol/src/version/v_1_15_2/game.rs create mode 100644 protocol/src/version/v_1_15_2/handshake.rs create mode 100644 protocol/src/version/v_1_15_2/login.rs create mode 100644 protocol/src/version/v_1_15_2/mod.rs create mode 100644 protocol/src/version/v_1_15_2/status.rs create mode 100644 protocol/src/version/v_1_16/game.rs create mode 100644 protocol/src/version/v_1_16/handshake.rs rename protocol/src/{packet => version/v_1_16}/login.rs (95%) create mode 100644 protocol/src/version/v_1_16/mod.rs create mode 100644 protocol/src/version/v_1_16/status.rs create mode 100644 protocol/src/version/v_1_16_1/game.rs create mode 100644 protocol/src/version/v_1_16_1/handshake.rs create mode 100644 protocol/src/version/v_1_16_1/login.rs create mode 100644 protocol/src/version/v_1_16_1/mod.rs create mode 100644 protocol/src/version/v_1_16_1/status.rs create mode 100644 protocol/src/version/v_1_16_2/game.rs create mode 100644 protocol/src/version/v_1_16_2/handshake.rs create mode 100644 protocol/src/version/v_1_16_2/login.rs create mode 100644 protocol/src/version/v_1_16_2/mod.rs create mode 100644 protocol/src/version/v_1_16_2/status.rs create mode 100644 protocol/src/version/v_1_16_rc1/game.rs create mode 100644 protocol/src/version/v_1_16_rc1/handshake.rs create mode 100644 protocol/src/version/v_1_16_rc1/login.rs create mode 100644 protocol/src/version/v_1_16_rc1/mod.rs create mode 100644 protocol/src/version/v_1_16_rc1/status.rs create mode 100644 protocol/src/version/v_1_8/game.rs create mode 100644 protocol/src/version/v_1_8/handshake.rs create mode 100644 protocol/src/version/v_1_8/login.rs create mode 100644 protocol/src/version/v_1_8/mod.rs create mode 100644 protocol/src/version/v_1_8/status.rs create mode 100644 protocol/src/version/v_1_9/game.rs create mode 100644 protocol/src/version/v_1_9/handshake.rs create mode 100644 protocol/src/version/v_1_9/login.rs create mode 100644 protocol/src/version/v_1_9/mod.rs create mode 100644 protocol/src/version/v_1_9/status.rs create mode 100644 protocol/src/version/v_1_9_1_pre2/game.rs create mode 100644 protocol/src/version/v_1_9_1_pre2/handshake.rs create mode 100644 protocol/src/version/v_1_9_1_pre2/login.rs create mode 100644 protocol/src/version/v_1_9_1_pre2/mod.rs create mode 100644 protocol/src/version/v_1_9_1_pre2/status.rs create mode 100644 protocol/src/version/v_1_9_2/game.rs create mode 100644 protocol/src/version/v_1_9_2/handshake.rs create mode 100644 protocol/src/version/v_1_9_2/login.rs create mode 100644 protocol/src/version/v_1_9_2/mod.rs create mode 100644 protocol/src/version/v_1_9_2/status.rs create mode 100644 protocol/src/version/v_1_9_4/game.rs create mode 100644 protocol/src/version/v_1_9_4/handshake.rs create mode 100644 protocol/src/version/v_1_9_4/login.rs create mode 100644 protocol/src/version/v_1_9_4/mod.rs create mode 100644 protocol/src/version/v_1_9_4/status.rs create mode 100644 protocol/src/version/v_20w13b/game.rs create mode 100644 protocol/src/version/v_20w13b/handshake.rs create mode 100644 protocol/src/version/v_20w13b/login.rs create mode 100644 protocol/src/version/v_20w13b/mod.rs create mode 100644 protocol/src/version/v_20w13b/status.rs diff --git a/protocol-generator/Cargo.toml b/protocol-generator/Cargo.toml index 9b325a4..d73dba6 100644 --- a/protocol-generator/Cargo.toml +++ b/protocol-generator/Cargo.toml @@ -10,7 +10,6 @@ repository = "https://github.com/eihwaz/minecraft-protocol" keywords = ["minecraft", "cli", "protocol", "packet", "io"] [dependencies] -structopt = "0.3" serde = "1.0.120" serde_json = "1.0" handlebars = "3.5.2" diff --git a/protocol-generator/minecraft-data b/protocol-generator/minecraft-data index e656aaf..cc155f3 160000 --- a/protocol-generator/minecraft-data +++ b/protocol-generator/minecraft-data @@ -1 +1 @@ -Subproject commit e656aafb77f477d3726ed46209f0d4bb7052a04b +Subproject commit cc155f399397755abeb9275de40fc82b65a252f4 diff --git a/protocol-generator/src/backend.rs b/protocol-generator/src/backend.rs index 316d929..4e2c43b 100644 --- a/protocol-generator/src/backend.rs +++ b/protocol-generator/src/backend.rs @@ -26,7 +26,8 @@ pub struct Packets { #[serde(untagged)] pub enum Data { Type(String), - Container(Vec), + Containers(Vec), + Container(Box), Mapper { #[serde(rename = "type")] mappings_type: String, diff --git a/protocol-generator/src/frontend.rs b/protocol-generator/src/frontend.rs index 49ce8f1..90d9dab 100644 --- a/protocol-generator/src/frontend.rs +++ b/protocol-generator/src/frontend.rs @@ -1,13 +1,16 @@ -use crate::frontend; +use crate::mappings::Mappings; +use crate::{backend, frontend, transformers}; use handlebars::{Handlebars, TemplateRenderError}; use serde::Serialize; use serde_json::json; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::fmt; use std::fmt::Display; +use std::fs::{create_dir_all, File}; use std::io::Write; +use std::path::Path; -#[derive(Debug, Copy, Clone)] +#[derive(Debug)] pub enum State { Handshake, Status, @@ -16,7 +19,7 @@ pub enum State { } impl State { - pub fn data_import(&self) -> &str { + pub fn data_import(&self) -> &'static str { match self { State::Handshake => "crate::data::handshake::*", State::Status => "crate::data::status::*", @@ -109,6 +112,8 @@ pub enum DataType { Int { var_int: bool, }, + #[serde(rename(serialize = "u32"))] + UnsignedInt, #[serde(rename(serialize = "i64"))] Long { var_long: bool, @@ -136,7 +141,7 @@ pub enum DataType { } impl DataType { - pub fn import<'a>(&self, state: &'a State) -> Option<&'a str> { + pub fn import(&self, state: &State) -> Option<&'static str> { match self { DataType::Uuid { .. } => Some("uuid::Uuid"), DataType::CompoundTag => Some("nbt::CompoundTag"), @@ -149,75 +154,156 @@ impl DataType { #[derive(Debug)] pub struct Protocol { - pub state: State, pub server_bound_packets: Vec, pub client_bound_packets: Vec, } impl Protocol { - pub fn new( - state: State, - server_bound_packets: Vec, - client_bound_packets: Vec, - ) -> Protocol { + pub fn new(server_bound_packets: Vec, client_bound_packets: Vec) -> Protocol { Protocol { - state, server_bound_packets, client_bound_packets, } } - pub fn data_type_imports(&self) -> HashSet<&str> { + pub fn data_type_imports(&self, state: &State) -> HashSet<&'static str> { self.server_bound_packets .iter() .chain(self.client_bound_packets.iter()) .flat_map(|p| p.fields.iter()) - .filter_map(|f| f.data_type.import(&self.state)) + .filter_map(|f| f.data_type.import(state)) .collect() } } -#[derive(Serialize)] -struct GenerateContext<'a> { - packet_enum_name: String, - packets: &'a Vec, +pub fn generate_rust_files( + versions_data: HashMap, + template_engine: &Handlebars, + mappings: &M, +) -> Result<(), TemplateRenderError> { + generate_versions_module_file(template_engine, versions_data.keys().cloned().collect())?; + + for (version, data_file) in versions_data.iter() { + println!("Generating protocol data for version {}", version); + + let protocol_handler: backend::ProtocolHandler = + serde_json::from_reader(data_file).expect("Failed to parse protocol data"); + + let frontend_protocols = + transformers::transform_protocol_handler(mappings, &protocol_handler); + + let formatted_version = version.replace(".", "_").replace("-", "_"); + + let folder_name = format!("protocol/src/version/v_{}", formatted_version); + let folder_path = Path::new(&folder_name); + + generate_protocol_module_file(template_engine, &folder_path)?; + + for (protocol, state) in frontend_protocols { + let file_name = format!("{}.rs", state.to_string().to_lowercase()); + + let mut file = File::create(folder_path.join(file_name)) + .expect("Failed to create protocol enum file"); + + generate_protocol_enum_header(template_engine, &protocol, &state, &mut file)?; + + generate_protocol_enum_content( + template_engine, + &protocol.server_bound_packets, + &state, + &Bound::Server, + &mut file, + )?; + + generate_protocol_enum_content( + template_engine, + &protocol.client_bound_packets, + &state, + &Bound::Client, + &mut file, + )?; + + generate_packets_structs(template_engine, &protocol.server_bound_packets, &mut file)?; + + generate_packets_structs(template_engine, &protocol.client_bound_packets, &mut file)?; + } + } + + Ok(()) +} + +fn generate_versions_module_file( + template_engine: &Handlebars, + versions: Vec, +) -> Result<(), TemplateRenderError> { + let mut file = + File::create("protocol/src/version/mod.rs").expect("Failed to create versions module file"); + + let ctx = json!({ "versions": versions }); + + template_engine.render_to_write("protocol_versions_module", &ctx, &mut file)?; + + Ok(()) } -pub fn generate_rust_file( +fn generate_protocol_module_file( + template_engine: &Handlebars, + folder_path: &Path, +) -> Result<(), TemplateRenderError> { + generate_module_file(template_engine, folder_path, "protocol_module") +} + +fn generate_module_file( + template_engine: &Handlebars, + folder_path: &Path, + name: &str, +) -> Result<(), TemplateRenderError> { + create_dir_all(folder_path).expect("Failed to create module folder"); + + let mut file = File::create(folder_path.join("mod.rs")).expect("Failed to create module file"); + + template_engine.render_to_write(name, &(), &mut file)?; + + Ok(()) +} + +fn generate_protocol_enum_header( + template_engine: &Handlebars, protocol: &frontend::Protocol, + state: &frontend::State, + write: &mut W, +) -> Result<(), TemplateRenderError> { + let imports = protocol.data_type_imports(state); + let ctx = json!({ "imports": imports }); + + template_engine.render_to_write("protocol_header", &ctx, write)?; + + Ok(()) +} + +fn generate_protocol_enum_content( template_engine: &Handlebars, - mut writer: W, + packets: &Vec, + state: &frontend::State, + bound: &frontend::Bound, + write: &mut W, ) -> Result<(), TemplateRenderError> { - let server_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server), - packets: &protocol.server_bound_packets, - }; - - let client_bound_ctx = GenerateContext { - packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client), - packets: &protocol.client_bound_packets, - }; - - let mut imports = vec![ - "crate::DecodeError", - "crate::Decoder", - "std::io::Read", - "minecraft_protocol_derive::Packet", - ]; - - imports.extend(protocol.data_type_imports().iter()); - - template_engine.render_to_write( - "packet_imports", - &json!({ "imports": imports }), - &mut writer, - )?; - - template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?; - - template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?; - template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?; + let protocol_enum_name = format!("{}Bound{}Packet", bound, state); + let ctx = json!({ "protocol_enum_name": protocol_enum_name, "packets": packets }); + + template_engine.render_to_write("protocol_enum", &ctx, write)?; + + Ok(()) +} + +fn generate_packets_structs( + template_engine: &Handlebars, + packets: &Vec, + write: &mut W, +) -> Result<(), TemplateRenderError> { + let ctx = json!({ "packets": packets }); + + template_engine.render_to_write("packets_structs", &ctx, write)?; Ok(()) } diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index ecc1d61..d16b6ca 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -1,7 +1,9 @@ use std::fs::File; use crate::mappings::CodeMappings; -use structopt::StructOpt; +use std::fs; +use std::io::Error; +use std::path::Path; pub mod backend; pub mod frontend; @@ -9,74 +11,47 @@ pub mod mappings; pub mod templates; pub mod transformers; -#[derive(StructOpt)] -#[structopt(name = "protocol-generator")] -struct Opt { - #[structopt(short, long, default_value = "1.14.4")] - protocol_version: String, -} - pub fn main() { - let opt: Opt = Opt::from_args(); - let template_engine = templates::create_template_engine(); - - let protocol_data_file_name = format!( - "protocol-generator/minecraft-data/data/pc/{}/protocol.json", - opt.protocol_version - ); - - let protocol_data_file = - File::open(protocol_data_file_name).expect("Failed to open protocol data file"); + let paths = fs::read_dir("protocol-generator/minecraft-data/data/pc/") + .expect("Failed to open data folder"); + + let versions_data = paths + .into_iter() + .map(|entry| { + entry + .expect("Failed to get dir entry") + .file_name() + .into_string() + .expect("Failed to get version string") + }) + .filter(|version| match version.as_str() { + "0.30c" => false, // A very old version with a lot of incompatibility. + "1.7" => false, // Requires some fixes to support. + _ => true, + }) + .filter_map(|version| { + let protocol_data_file_name = format!( + "protocol-generator/minecraft-data/data/pc/{}/protocol.json", + version + ); + + let protocol_data_file_path = Path::new(&protocol_data_file_name); + + match protocol_data_file_path.exists() { + true => { + let protocol_data_file = File::open(protocol_data_file_path) + .expect("Failed to open protocol data file"); + + Some((version, protocol_data_file)) + } + false => None, + } + }) + .collect(); - let protocol_handler: backend::ProtocolHandler = - serde_json::from_reader(protocol_data_file).expect("Failed to parse protocol data"); - - let mappings = CodeMappings {}; - - let protocols = vec![ - ( - transformers::transform_protocol( - &mappings, - frontend::State::Handshake, - &protocol_handler.handshaking, - ), - frontend::State::Handshake, - ), - ( - transformers::transform_protocol( - &mappings, - frontend::State::Status, - &protocol_handler.status, - ), - frontend::State::Status, - ), - ( - transformers::transform_protocol( - &mappings, - frontend::State::Login, - &protocol_handler.login, - ), - frontend::State::Login, - ), - ( - transformers::transform_protocol( - &mappings, - frontend::State::Game, - &protocol_handler.game, - ), - frontend::State::Game, - ), - ]; - - for (protocol, state) in protocols { - let file_name = format!( - "protocol/src/packet/{}.rs", - state.to_string().to_lowercase() - ); - - let file = File::create(file_name).expect("Failed to create file"); + let template_engine = templates::create_template_engine(); + let mappings = CodeMappings::new(); - frontend::generate_rust_file(&protocol, &template_engine, &file) - .expect("Failed to generate rust file"); - } + frontend::generate_rust_files(versions_data, &template_engine, &mappings) + .expect("Failed to generate rust files"); } diff --git a/protocol-generator/src/mappings.rs b/protocol-generator/src/mappings.rs index 5716322..692cdca 100644 --- a/protocol-generator/src/mappings.rs +++ b/protocol-generator/src/mappings.rs @@ -15,6 +15,12 @@ pub trait Mappings { pub struct CodeMappings {} +impl CodeMappings { + pub fn new() -> CodeMappings { + CodeMappings {} + } +} + impl Mappings for CodeMappings { fn rename_packet( &self, @@ -50,15 +56,15 @@ impl Mappings for CodeMappings { fn change_field_type(&self, packet_name: &str, field: frontend::Field) -> frontend::Field { match (packet_name, field.name.as_str()) { - ("StatusResponse", "response") => field.change_type(frontend::DataType::RefType { - ref_name: "ServerStatus".to_owned(), - }), - ("Success", "uuid") => field.change_type(frontend::DataType::Uuid { hyphenated: true }), - ("Disconnect", "reason") => field.change_type(frontend::DataType::Chat), - ("ClientBoundChat", "message") => field.change_type(frontend::DataType::Chat), - ("ClientBoundChat", "position") => field.change_type(frontend::DataType::RefType { - ref_name: "MessagePosition".to_owned(), - }), + // ("StatusResponse", "response") => field.change_type(frontend::DataType::RefType { + // ref_name: "ServerStatus".to_owned(), + // }), + // ("Success", "uuid") => field.change_type(frontend::DataType::Uuid { hyphenated: true }), + // ("Disconnect", "reason") => field.change_type(frontend::DataType::Chat), + // ("ClientBoundChat", "message") => field.change_type(frontend::DataType::Chat), + // ("ClientBoundChat", "position") => field.change_type(frontend::DataType::RefType { + // ref_name: "MessagePosition".to_owned(), + // }), _ => field, } } diff --git a/protocol-generator/src/templates.rs b/protocol-generator/src/templates.rs index 2bc1993..207eec3 100644 --- a/protocol-generator/src/templates.rs +++ b/protocol-generator/src/templates.rs @@ -6,30 +6,25 @@ pub fn create_template_engine() -> Handlebars<'static> { template_engine.register_helper("snake_case", Box::new(format_snake_case)); template_engine.register_helper("packet_id", Box::new(format_packet_id)); + template_engine.register_helper( + "protocol_version_module", + Box::new(format_protocol_version_module), + ); template_engine.register_escape_fn(|s| s.to_owned()); - template_engine - .register_template_file( - "packet_imports", - "protocol-generator/templates/packet_imports.hbs", - ) - .expect("Failed to register template"); + register_template_file(&mut template_engine, "protocol_versions_module"); + register_template_file(&mut template_engine, "protocol_module"); + register_template_file(&mut template_engine, "protocol_enum"); + register_template_file(&mut template_engine, "packets_structs"); + register_template_file(&mut template_engine, "protocol_header"); template_engine - .register_template_file( - "packet_enum", - "protocol-generator/templates/packet_enum.hbs", - ) - .expect("Failed to register template"); +} +fn register_template_file(template_engine: &mut Handlebars, name: &str) { template_engine - .register_template_file( - "packet_structs", - "protocol-generator/templates/packet_structs.hbs", - ) + .register_template_file(name, format!("protocol-generator/templates/{}.hbs", name)) .expect("Failed to register template"); - - template_engine } fn format_snake_case( @@ -71,3 +66,24 @@ fn format_packet_id( out.write(packet_id_str.as_ref())?; Ok(()) } + +fn format_protocol_version_module( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output, +) -> Result<(), RenderError> { + let version = h + .param(0) + .and_then(|v| v.value().as_str()) + .ok_or(RenderError::new( + "Param 0 with str type is required for packet id helper.", + ))? as &str; + + let formatted_protocol_module_version = + format!("v_{}", version.replace(".", "_").replace("-", "_")); + + out.write(formatted_protocol_module_version.as_ref())?; + Ok(()) +} diff --git a/protocol-generator/src/transformers.rs b/protocol-generator/src/transformers.rs index 155bb8e..7e04aeb 100644 --- a/protocol-generator/src/transformers.rs +++ b/protocol-generator/src/transformers.rs @@ -1,12 +1,34 @@ -use crate::backend::Data; use crate::mappings::Mappings; use crate::{backend, frontend}; use heck::{CamelCase, SnakeCase}; use std::collections::HashMap; -pub fn transform_protocol( +pub fn transform_protocol_handler( + mappings: &M, + protocol_handler: &backend::ProtocolHandler, +) -> Vec<(frontend::Protocol, frontend::State)> { + vec![ + ( + transform_protocol::(&mappings, &protocol_handler.handshaking), + frontend::State::Handshake, + ), + ( + transform_protocol::(&mappings, &protocol_handler.status), + frontend::State::Status, + ), + ( + transform_protocol::(&mappings, &protocol_handler.login), + frontend::State::Login, + ), + ( + transform_protocol::(&mappings, &protocol_handler.game), + frontend::State::Game, + ), + ] +} + +fn transform_protocol( mappings: &M, - state: frontend::State, protocol: &backend::Protocol, ) -> frontend::Protocol { let server_bound_packets = transform_packets( @@ -24,7 +46,6 @@ pub fn transform_protocol( ); frontend::Protocol { - state, server_bound_packets, client_bound_packets, } @@ -36,7 +57,7 @@ fn get_packet_ids(packets: &backend::Packets) -> HashMap { .get("packet") .and_then(|d| d.get(1)) .and_then(|d| match d { - backend::Data::Container(data) => data.get(0), + backend::Data::Containers(data) => data.get(0), _ => None, }) .and_then(|c| match c { @@ -92,7 +113,7 @@ fn transform_packets( let mut fields = vec![]; for data in data_vec { - if let backend::Data::Container(container_vec) = data { + if let backend::Data::Containers(container_vec) = data { for container in container_vec { match container { backend::Container::Value { name, data } => { @@ -183,6 +204,7 @@ fn transform_data_type(name: &str) -> Option { "i64" => Some(frontend::DataType::Long { var_long: false }), "u8" => Some(frontend::DataType::UnsignedByte), "u16" => Some(frontend::DataType::UnsignedShort), + "u32" => Some(frontend::DataType::UnsignedInt), "f32" => Some(frontend::DataType::Float), "f64" => Some(frontend::DataType::Double), "varint" => Some(frontend::DataType::Int { var_int: true }), diff --git a/protocol-generator/templates/packet_structs.hbs b/protocol-generator/templates/packets_structs.hbs similarity index 98% rename from protocol-generator/templates/packet_structs.hbs rename to protocol-generator/templates/packets_structs.hbs index c6d4822..4a4b1b6 100644 --- a/protocol-generator/templates/packet_structs.hbs +++ b/protocol-generator/templates/packets_structs.hbs @@ -21,4 +21,4 @@ pub struct {{p.name}} { {{~/each}} } {{/if}} -{{~/each}} +{{~/each}} \ No newline at end of file diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/protocol_enum.hbs similarity index 85% rename from protocol-generator/templates/packet_enum.hbs rename to protocol-generator/templates/protocol_enum.hbs index c596a16..9fcc228 100644 --- a/protocol-generator/templates/packet_enum.hbs +++ b/protocol-generator/templates/protocol_enum.hbs @@ -1,15 +1,15 @@ {{~#if packets}} -pub enum {{packet_enum_name}} { +pub enum {{protocol_enum_name}} { {{~#each packets as |p|}} - {{p.name}}{{#if p.fields}}({{p.name}}){{/if}}{{#unless @last}},{{/unless}} + {{p.name}}{{#if p.fields}}({{p.name}}){{/if}}, {{~/each}} } -impl {{packet_enum_name}} { +impl {{protocol_enum_name}} { pub fn get_type_id(&self) -> u8 { match self { {{~#each packets as |p|}} - Self::{{p.name}}{{#if p.fields}}(_){{/if}} => {{packet_id p.id}}{{#unless @last}},{{/unless}} + Self::{{p.name}}{{#if p.fields}}(_){{/if}} => {{packet_id p.id}}, {{~/each}} } } @@ -36,7 +36,7 @@ impl {{packet_enum_name}} { {{~#if p.fields}} let {{snake_case p.name}} = {{p.name}} { {{~#each p.fields as |f|}} - {{f.name}}{{#unless @last}},{{/unless}} + {{f.name}}, {{~/each}} }; diff --git a/protocol-generator/templates/protocol_header.hbs b/protocol-generator/templates/protocol_header.hbs new file mode 100644 index 0000000..7a835db --- /dev/null +++ b/protocol-generator/templates/protocol_header.hbs @@ -0,0 +1,10 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use std::io::Read; +use minecraft_protocol_derive::Packet; + +{{#each imports as |i|~}} +use {{i}}; +{{/each~}} diff --git a/protocol-generator/templates/packet_imports.hbs b/protocol-generator/templates/protocol_module.hbs similarity index 56% rename from protocol-generator/templates/packet_imports.hbs rename to protocol-generator/templates/protocol_module.hbs index a97ad24..5b823c9 100644 --- a/protocol-generator/templates/packet_imports.hbs +++ b/protocol-generator/templates/protocol_module.hbs @@ -1,5 +1,6 @@ // This file is automatically generated. // It is not intended for manual editing. -{{#each imports as |i|~}} -use {{i}}; -{{/each~}} +pub mod handshake; +pub mod status; +pub mod login; +pub mod game; diff --git a/protocol-generator/templates/protocol_versions_module.hbs b/protocol-generator/templates/protocol_versions_module.hbs new file mode 100644 index 0000000..0d562af --- /dev/null +++ b/protocol-generator/templates/protocol_versions_module.hbs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +{{#each versions as |v|~}} +#[cfg(feature = "{{v}}")] +pub mod {{protocol_version_module v}}; +{{/each~}} diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs deleted file mode 100644 index fdc6860..0000000 --- a/protocol/src/data/game.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::impl_enum_encoder_decoder; -use nbt::CompoundTag; -use num_derive::{FromPrimitive, ToPrimitive}; -use std::io::{Read, Write}; - -#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] -pub enum MessagePosition { - Chat, - System, - HotBar, -} - -impl_enum_encoder_decoder!(MessagePosition); - -#[derive(Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] -pub enum GameMode { - Survival = 0, - Creative = 1, - Adventure = 2, - Spectator = 3, - Hardcore = 8, -} - -impl_enum_encoder_decoder!(GameMode); - -#[derive(Debug, Eq, PartialEq)] -pub struct Position { - pub x: i32, - pub y: i16, - pub z: i32, -} - -#[derive(Debug)] -pub struct Slot { - pub id: i32, - pub amount: u8, - pub compound_tag: CompoundTag, -} - -#[derive(Debug)] -pub struct Metadata {} - -#[derive(Debug)] -pub struct TagsMap {} - -#[derive(Debug)] -pub struct ParticleData {} diff --git a/protocol/src/data/mod.rs b/protocol/src/data/mod.rs index 02b3360..a9b9724 100644 --- a/protocol/src/data/mod.rs +++ b/protocol/src/data/mod.rs @@ -1,3 +1,2 @@ pub mod chat; -pub mod game; -pub mod status; +pub mod server_status; diff --git a/protocol/src/data/status.rs b/protocol/src/data/server_status.rs similarity index 100% rename from protocol/src/data/status.rs rename to protocol/src/data/server_status.rs diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 9c3adbd..0ec9af1 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -10,12 +10,11 @@ use uuid::Uuid; use data::chat::Message; -use crate::data::game::{Metadata, ParticleData, Position, Slot, TagsMap}; use crate::error::{DecodeError, EncodeError}; pub mod data; pub mod error; -pub mod packet; +pub mod version; /// Current supported protocol version. pub const PROTOCOL_VERSION: u32 = 498; @@ -510,123 +509,6 @@ macro_rules! impl_json_encoder_decoder ( ); ); -impl Encoder for Position { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - let encoded_x = (self.x & 0x3FFFFFF) as i64; - let encoded_y = (self.y & 0xFFF) as i64; - let encoded_z = (self.z & 0x3FFFFFF) as i64; - - writer.write_i64::((encoded_x << 38) | (encoded_z << 12) | encoded_y)?; - Ok(()) - } -} - -impl Decoder for Position { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - let encoded = reader.read_i64::()?; - - let x = (encoded >> 38) as i32; - let y = (encoded & 0xFFF) as i16; - let z = (encoded << 26 >> 38) as i32; - - Ok(Position { x, y, z }) - } -} - -impl Encoder for Option { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - match self { - Some(slot) => { - writer.write_bool(true)?; - slot.encode(writer) - } - None => writer.write_bool(false), - } - } -} - -impl Decoder for Option { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - if reader.read_bool()? { - Ok(Some(Slot::decode(reader)?)) - } else { - Ok(None) - } - } -} - -impl Encoder for Slot { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - writer.write_var_i32(self.id)?; - writer.write_u8(self.amount)?; - writer.write_compound_tag(&self.compound_tag)?; - - Ok(()) - } -} - -impl Decoder for Slot { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - let id = reader.read_var_i32()?; - let amount = reader.read_u8()?; - let compound_tag = reader.read_compound_tag()?; - - Ok(Slot { - id, - amount, - compound_tag, - }) - } -} - -impl Encoder for Metadata { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - unimplemented!() - } -} - -impl Decoder for Metadata { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - unimplemented!() - } -} - -impl Encoder for TagsMap { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - unimplemented!() - } -} - -impl Decoder for TagsMap { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - unimplemented!() - } -} - -impl Encoder for ParticleData { - fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { - unimplemented!() - } -} - -impl Decoder for ParticleData { - type Output = Self; - - fn decode(reader: &mut R) -> Result { - unimplemented!() - } -} - mod var_int { use std::io::{Read, Write}; diff --git a/protocol/src/packet/mod.rs b/protocol/src/packet/mod.rs deleted file mode 100644 index 29a91c1..0000000 --- a/protocol/src/packet/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod game; -pub mod handshake; -pub mod login; -pub mod status; diff --git a/protocol/src/version/mod.rs b/protocol/src/version/mod.rs new file mode 100644 index 0000000..c2ed117 --- /dev/null +++ b/protocol/src/version/mod.rs @@ -0,0 +1,72 @@ +// This file is automatically generated. +// It is not intended for manual editing. +#[cfg(feature = "15w40b")] +pub mod v_15w40b; +#[cfg(feature = "16w20a")] +pub mod v_16w20a; +#[cfg(feature = "16w35a")] +pub mod v_16w35a; +#[cfg(feature = "17w15a")] +pub mod v_17w15a; +#[cfg(feature = "17w18b")] +pub mod v_17w18b; +#[cfg(feature = "17w50a")] +pub mod v_17w50a; +#[cfg(feature = "1.10")] +pub mod v_1_10; +#[cfg(feature = "1.10-pre1")] +pub mod v_1_10_pre1; +#[cfg(feature = "1.11")] +pub mod v_1_11; +#[cfg(feature = "1.12")] +pub mod v_1_12; +#[cfg(feature = "1.12.1")] +pub mod v_1_12_1; +#[cfg(feature = "1.12.2")] +pub mod v_1_12_2; +#[cfg(feature = "1.12-pre4")] +pub mod v_1_12_pre4; +#[cfg(feature = "1.13")] +pub mod v_1_13; +#[cfg(feature = "1.13.1")] +pub mod v_1_13_1; +#[cfg(feature = "1.13.2")] +pub mod v_1_13_2; +#[cfg(feature = "1.13.2-pre1")] +pub mod v_1_13_2_pre1; +#[cfg(feature = "1.13.2-pre2")] +pub mod v_1_13_2_pre2; +#[cfg(feature = "1.14")] +pub mod v_1_14; +#[cfg(feature = "1.14.1")] +pub mod v_1_14_1; +#[cfg(feature = "1.14.3")] +pub mod v_1_14_3; +#[cfg(feature = "1.14.4")] +pub mod v_1_14_4; +#[cfg(feature = "1.15")] +pub mod v_1_15; +#[cfg(feature = "1.15.1")] +pub mod v_1_15_1; +#[cfg(feature = "1.15.2")] +pub mod v_1_15_2; +#[cfg(feature = "1.16")] +pub mod v_1_16; +#[cfg(feature = "1.16.1")] +pub mod v_1_16_1; +#[cfg(feature = "1.16.2")] +pub mod v_1_16_2; +#[cfg(feature = "1.16-rc1")] +pub mod v_1_16_rc1; +#[cfg(feature = "1.8")] +pub mod v_1_8; +#[cfg(feature = "1.9")] +pub mod v_1_9; +#[cfg(feature = "1.9.1-pre2")] +pub mod v_1_9_1_pre2; +#[cfg(feature = "1.9.2")] +pub mod v_1_9_2; +#[cfg(feature = "1.9.4")] +pub mod v_1_9_4; +#[cfg(feature = "20w13b")] +pub mod v_20w13b; diff --git a/protocol/src/version/v_15w40b/game.rs b/protocol/src/version/v_15w40b/game.rs new file mode 100644 index 0000000..9031633 --- /dev/null +++ b/protocol/src/version/v_15w40b/game.rs @@ -0,0 +1,2555 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundChat(ServerBoundChat), + UseEntity(UseEntity), + Flying(Flying), + ServerBoundPosition(ServerBoundPosition), + Look(Look), + PositionLook(PositionLook), + BlockDig(BlockDig), + BlockPlace(BlockPlace), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + ArmAnimation(ArmAnimation), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ServerBoundCloseWindow(ServerBoundCloseWindow), + WindowClick(WindowClick), + ServerBoundTransaction(ServerBoundTransaction), + SetCreativeSlot(SetCreativeSlot), + EnchantItem(EnchantItem), + ServerBoundUpdateSign(ServerBoundUpdateSign), + ServerBoundAbilities(ServerBoundAbilities), + ServerBoundTabComplete(ServerBoundTabComplete), + Settings(Settings), + ClientCommand(ClientCommand), + ServerBoundCustomPayload(ServerBoundCustomPayload), + Spectate(Spectate), + ResourcePackReceive(ResourcePackReceive), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::ServerBoundKeepAlive(_) => 0x0A, + Self::ServerBoundChat(_) => 0x01, + Self::UseEntity(_) => 0x09, + Self::Flying(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x0B, + Self::Look(_) => 0x0D, + Self::PositionLook(_) => 0x0C, + Self::BlockDig(_) => 0x10, + Self::BlockPlace(_) => 0x19, + Self::ServerBoundHeldItemSlot(_) => 0x14, + Self::ArmAnimation(_) => 0x17, + Self::EntityAction(_) => 0x11, + Self::SteerVehicle(_) => 0x12, + Self::ServerBoundCloseWindow(_) => 0x07, + Self::WindowClick(_) => 0x06, + Self::ServerBoundTransaction(_) => 0x04, + Self::SetCreativeSlot(_) => 0x15, + Self::EnchantItem(_) => 0x05, + Self::ServerBoundUpdateSign(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x0F, + Self::ServerBoundTabComplete(_) => 0x00, + Self::Settings(_) => 0x03, + Self::ClientCommand(_) => 0x02, + Self::ServerBoundCustomPayload(_) => 0x08, + Self::Spectate(_) => 0x18, + Self::ResourcePackReceive(_) => 0x13, + Self::UseItem(_) => 0x1A, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x0A => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x01 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x09 => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x0B => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0C => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x10 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x14 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x17 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x11 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x12 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x07 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x06 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x04 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x15 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x05 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x16 => { + let server_bound_update_sign = ServerBoundUpdateSign::decode(reader)?; + + Ok(Self::ServerBoundUpdateSign(server_bound_update_sign)) + } + 0x0F => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x00 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x02 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x08 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x18 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x13 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x1A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn server_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let server_bound_update_sign = ServerBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ServerBoundUpdateSign(server_bound_update_sign) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn server_bound_tab_complete(text: String, block: Position) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { text, block }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn client_command(payload: i32) -> Self { + let client_command = ClientCommand { payload }; + + Self::ClientCommand(client_command) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + ClientBoundKeepAlive(ClientBoundKeepAlive), + JoinGame(JoinGame), + ClientBoundChat(ClientBoundChat), + UpdateTime(UpdateTime), + EntityEquipment(EntityEquipment), + SpawnPosition(SpawnPosition), + UpdateHealth(UpdateHealth), + Respawn(Respawn), + ClientBoundPosition(ClientBoundPosition), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + Bed(Bed), + Animation(Animation), + NamedEntitySpawn(NamedEntitySpawn), + Collect(Collect), + SpawnEntity(SpawnEntity), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + EntityVelocity(EntityVelocity), + EntityDestroy, + Entity(Entity), + RelEntityMove(RelEntityMove), + EntityLook(EntityLook), + EntityMoveLook(EntityMoveLook), + EntityTeleport(EntityTeleport), + EntityHeadRotation(EntityHeadRotation), + EntityStatus(EntityStatus), + AttachEntity(AttachEntity), + EntityMetadata(EntityMetadata), + EntityEffect(EntityEffect), + RemoveEntityEffect(RemoveEntityEffect), + Experience(Experience), + UpdateAttributes(UpdateAttributes), + MapChunk(MapChunk), + MultiBlockChange(MultiBlockChange), + BlockChange(BlockChange), + BlockAction(BlockAction), + BlockBreakAnimation(BlockBreakAnimation), + Explosion(Explosion), + WorldEvent(WorldEvent), + NamedSoundEffect(NamedSoundEffect), + WorldParticles(WorldParticles), + GameStateChange(GameStateChange), + SpawnEntityWeather(SpawnEntityWeather), + OpenWindow(OpenWindow), + ClientBoundCloseWindow(ClientBoundCloseWindow), + SetSlot(SetSlot), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundUpdateSign(ClientBoundUpdateSign), + Map(Map), + TileEntityData(TileEntityData), + OpenSignEntity(OpenSignEntity), + Statistics, + PlayerInfo(PlayerInfo), + ClientBoundAbilities(ClientBoundAbilities), + ClientBoundTabComplete, + ScoreboardObjective(ScoreboardObjective), + ScoreboardScore(ScoreboardScore), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + ScoreboardTeam(ScoreboardTeam), + ClientBoundCustomPayload(ClientBoundCustomPayload), + KickDisconnect(KickDisconnect), + Difficulty(Difficulty), + CombatEvent(CombatEvent), + Camera(Camera), + WorldBorder(WorldBorder), + Title(Title), + SetCompression(SetCompression), + PlayerlistHeader(PlayerlistHeader), + ResourcePackSend(ResourcePackSend), + BossBar(BossBar), + SetCooldown(SetCooldown), + UnloadChunk(UnloadChunk), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::JoinGame(_) => 0x24, + Self::ClientBoundChat(_) => 0x0F, + Self::UpdateTime(_) => 0x43, + Self::EntityEquipment(_) => 0x3C, + Self::SpawnPosition(_) => 0x42, + Self::UpdateHealth(_) => 0x3E, + Self::Respawn(_) => 0x33, + Self::ClientBoundPosition(_) => 0x2E, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::Bed(_) => 0x2F, + Self::Animation(_) => 0x06, + Self::NamedEntitySpawn(_) => 0x05, + Self::Collect(_) => 0x47, + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::EntityVelocity(_) => 0x3B, + Self::EntityDestroy => 0x30, + Self::Entity(_) => 0x29, + Self::RelEntityMove(_) => 0x26, + Self::EntityLook(_) => 0x28, + Self::EntityMoveLook(_) => 0x27, + Self::EntityTeleport(_) => 0x48, + Self::EntityHeadRotation(_) => 0x34, + Self::EntityStatus(_) => 0x1A, + Self::AttachEntity(_) => 0x3A, + Self::EntityMetadata(_) => 0x39, + Self::EntityEffect(_) => 0x4A, + Self::RemoveEntityEffect(_) => 0x31, + Self::Experience(_) => 0x3D, + Self::UpdateAttributes(_) => 0x49, + Self::MapChunk(_) => 0x20, + Self::MultiBlockChange(_) => 0x10, + Self::BlockChange(_) => 0x0B, + Self::BlockAction(_) => 0x0A, + Self::BlockBreakAnimation(_) => 0x08, + Self::Explosion(_) => 0x1B, + Self::WorldEvent(_) => 0x21, + Self::NamedSoundEffect(_) => 0x23, + Self::WorldParticles(_) => 0x22, + Self::GameStateChange(_) => 0x1E, + Self::SpawnEntityWeather(_) => 0x02, + Self::OpenWindow(_) => 0x13, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::SetSlot(_) => 0x16, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundUpdateSign(_) => 0x45, + Self::Map(_) => 0x25, + Self::TileEntityData(_) => 0x09, + Self::OpenSignEntity(_) => 0x2A, + Self::Statistics => 0x07, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2B, + Self::ClientBoundTabComplete => 0x0E, + Self::ScoreboardObjective(_) => 0x3F, + Self::ScoreboardScore(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::ScoreboardTeam(_) => 0x40, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::KickDisconnect(_) => 0x19, + Self::Difficulty(_) => 0x0D, + Self::CombatEvent(_) => 0x2C, + Self::Camera(_) => 0x36, + Self::WorldBorder(_) => 0x35, + Self::Title(_) => 0x44, + Self::SetCompression(_) => 0x1D, + Self::PlayerlistHeader(_) => 0x46, + Self::ResourcePackSend(_) => 0x32, + Self::BossBar(_) => 0x0C, + Self::SetCooldown(_) => 0x17, + Self::UnloadChunk(_) => 0x1C, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x43 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x42 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x47 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x29 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x48 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x1A => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x4A => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_attributes = UpdateAttributes::decode(reader)?; + + Ok(Self::UpdateAttributes(update_attributes)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x1B => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x45 => { + let client_bound_update_sign = ClientBoundUpdateSign::decode(reader)?; + + Ok(Self::ClientBoundUpdateSign(client_bound_update_sign)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x07 => Ok(Self::Statistics), + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x41 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x40 => { + let scoreboard_team = ScoreboardTeam::decode(reader)?; + + Ok(Self::ScoreboardTeam(scoreboard_team)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x44 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x1D => { + let set_compression = SetCompression::decode(reader)?; + + Ok(Self::SetCompression(set_compression)) + } + 0x46 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x1C => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i8, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn client_bound_position(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, flags: i8) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn spawn_entity( + entity_id: i32, + entity_uuid: Uuid, + type_: i8, + x: i32, + y: i32, + z: i32, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + entity_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: i32, y: i32, z: i32, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i8, d_y: i8, d_z: i8, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i8, + d_y: i8, + d_z: i8, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_teleport( + entity_id: i32, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32, leash: bool) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + leash, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: bool, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_attributes(entity_id: i32) -> Self { + let update_attributes = UpdateAttributes { entity_id }; + + Self::UpdateAttributes(update_attributes) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn named_sound_effect( + sound_name: String, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: i32, y: i32, z: i32) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let client_bound_update_sign = ClientBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ClientBoundUpdateSign(client_bound_update_sign) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn scoreboard_team(team: String, mode: i8) -> Self { + let scoreboard_team = ScoreboardTeam { team, mode }; + + Self::ScoreboardTeam(scoreboard_team) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn set_compression(threshold: i32) -> Self { + let set_compression = SetCompression { threshold }; + + Self::SetCompression(set_compression) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub block: Position, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub payload: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i8, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: i8, + pub x: i32, + pub y: i32, + pub z: i32, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i8, + pub d_y: i8, + pub d_z: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i8, + pub d_y: i8, + pub d_z: i8, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, + pub leash: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: i32, + pub y: i32, + pub z: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardTeam { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SetCompression { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} diff --git a/protocol/src/packet/handshake.rs b/protocol/src/version/v_15w40b/handshake.rs similarity index 94% rename from protocol/src/packet/handshake.rs rename to protocol/src/version/v_15w40b/handshake.rs index 90d4683..0ca7960 100644 --- a/protocol/src/packet/handshake.rs +++ b/protocol/src/version/v_15w40b/handshake.rs @@ -5,11 +5,11 @@ use crate::Decoder; use minecraft_protocol_derive::Packet; use std::io::Read; -pub enum HandshakeServerBoundPacket { +pub enum ServerBoundHandshakePacket { SetProtocol(SetProtocol), } -impl HandshakeServerBoundPacket { +impl ServerBoundHandshakePacket { pub fn get_type_id(&self) -> u8 { match self { Self::SetProtocol(_) => 0x00, diff --git a/protocol/src/version/v_15w40b/login.rs b/protocol/src/version/v_15w40b/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_15w40b/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_15w40b/mod.rs b/protocol/src/version/v_15w40b/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_15w40b/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/packet/status.rs b/protocol/src/version/v_15w40b/status.rs similarity index 89% rename from protocol/src/packet/status.rs rename to protocol/src/version/v_15w40b/status.rs index 6392a83..20fb7b7 100644 --- a/protocol/src/packet/status.rs +++ b/protocol/src/version/v_15w40b/status.rs @@ -1,17 +1,16 @@ // This file is automatically generated. // It is not intended for manual editing. -use crate::data::status::*; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; use std::io::Read; -pub enum StatusServerBoundPacket { +pub enum ServerBoundStatusPacket { StatusRequest, PingRequest(PingRequest), } -impl StatusServerBoundPacket { +impl ServerBoundStatusPacket { pub fn get_type_id(&self) -> u8 { match self { Self::StatusRequest => 0x00, @@ -42,12 +41,12 @@ impl StatusServerBoundPacket { } } -pub enum StatusClientBoundPacket { +pub enum ClientBoundStatusPacket { StatusResponse(StatusResponse), PingResponse(PingResponse), } -impl StatusClientBoundPacket { +impl ClientBoundStatusPacket { pub fn get_type_id(&self) -> u8 { match self { Self::StatusResponse(_) => 0x00, @@ -71,7 +70,7 @@ impl StatusClientBoundPacket { } } - pub fn status_response(response: ServerStatus) -> Self { + pub fn status_response(response: String) -> Self { let status_response = StatusResponse { response }; Self::StatusResponse(status_response) @@ -91,7 +90,7 @@ pub struct PingRequest { #[derive(Packet, Debug)] pub struct StatusResponse { - pub response: ServerStatus, + pub response: String, } #[derive(Packet, Debug)] diff --git a/protocol/src/version/v_16w20a/game.rs b/protocol/src/version/v_16w20a/game.rs new file mode 100644 index 0000000..a656231 --- /dev/null +++ b/protocol/src/version/v_16w20a/game.rs @@ -0,0 +1,2685 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_16w20a/handshake.rs b/protocol/src/version/v_16w20a/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_16w20a/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_16w20a/login.rs b/protocol/src/version/v_16w20a/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_16w20a/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_16w20a/mod.rs b/protocol/src/version/v_16w20a/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_16w20a/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_16w20a/status.rs b/protocol/src/version/v_16w20a/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_16w20a/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_16w35a/game.rs b/protocol/src/version/v_16w35a/game.rs new file mode 100644 index 0000000..51ad83d --- /dev/null +++ b/protocol/src/version/v_16w35a/game.rs @@ -0,0 +1,2692 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_16w35a/handshake.rs b/protocol/src/version/v_16w35a/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_16w35a/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_16w35a/login.rs b/protocol/src/version/v_16w35a/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_16w35a/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_16w35a/mod.rs b/protocol/src/version/v_16w35a/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_16w35a/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_16w35a/status.rs b/protocol/src/version/v_16w35a/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_16w35a/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_17w15a/game.rs b/protocol/src/version/v_17w15a/game.rs new file mode 100644 index 0000000..f671a15 --- /dev/null +++ b/protocol/src/version/v_17w15a/game.rs @@ -0,0 +1,2781 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + PrepareCraftingGrid(PrepareCraftingGrid), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::PrepareCraftingGrid(_) => 0x01, + Self::ServerBoundTabComplete(_) => 0x02, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0B, + Self::ServerBoundKeepAlive(_) => 0x0C, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x10, + Self::ServerBoundVehicleMove(_) => 0x11, + Self::SteerBoat(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x19, + Self::SetCreativeSlot(_) => 0x1A, + Self::UpdateSign(_) => 0x1B, + Self::ArmAnimation(_) => 0x1C, + Self::Spectate(_) => 0x1D, + Self::BlockPlace(_) => 0x1E, + Self::UseItem(_) => 0x1F, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let prepare_crafting_grid = PrepareCraftingGrid::decode(reader)?; + + Ok(Self::PrepareCraftingGrid(prepare_crafting_grid)) + } + 0x02 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0B => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0C => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x10 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x11 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x12 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x19 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1A => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1B => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1C => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1D => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1E => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1F => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn prepare_crafting_grid(window_id: u8, action_number: u16) -> Self { + let prepare_crafting_grid = PrepareCraftingGrid { + window_id, + action_number, + }; + + Self::PrepareCraftingGrid(prepare_crafting_grid) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: u32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x08, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete => 0x0F, + Self::ClientBoundChat(_) => 0x10, + Self::MultiBlockChange(_) => 0x11, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::JoinGame(_) => 0x24, + Self::Map(_) => 0x25, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x29, + Self::ClientBoundVehicleMove(_) => 0x2A, + Self::OpenSignEntity(_) => 0x2B, + Self::ClientBoundAbilities(_) => 0x2C, + Self::CombatEvent(_) => 0x2D, + Self::PlayerInfo(_) => 0x2E, + Self::ClientBoundPosition(_) => 0x2F, + Self::Bed(_) => 0x30, + Self::UnlockRecipes(_) => 0x31, + Self::EntityDestroy => 0x32, + Self::RemoveEntityEffect(_) => 0x33, + Self::ResourcePackSend(_) => 0x34, + Self::Respawn(_) => 0x35, + Self::EntityHeadRotation(_) => 0x36, + Self::WorldBorder(_) => 0x37, + Self::Camera(_) => 0x38, + Self::ClientBoundHeldItemSlot(_) => 0x39, + Self::ScoreboardDisplayObjective(_) => 0x3A, + Self::EntityMetadata(_) => 0x3B, + Self::AttachEntity(_) => 0x3C, + Self::EntityVelocity(_) => 0x3D, + Self::EntityEquipment(_) => 0x3E, + Self::Experience(_) => 0x3F, + Self::UpdateHealth(_) => 0x40, + Self::ScoreboardObjective(_) => 0x41, + Self::SetPassengers(_) => 0x42, + Self::Teams(_) => 0x43, + Self::ScoreboardScore(_) => 0x44, + Self::SpawnPosition(_) => 0x45, + Self::UpdateTime(_) => 0x46, + Self::Title(_) => 0x47, + Self::SoundEffect(_) => 0x48, + Self::PlayerlistHeader(_) => 0x49, + Self::Collect(_) => 0x4A, + Self::EntityTeleport(_) => 0x4B, + Self::EntityUpdateAttributes(_) => 0x4C, + Self::EntityEffect(_) => 0x4D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0F => Ok(Self::ClientBoundTabComplete), + 0x10 => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x11 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x29 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2A => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2B => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2C => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2D => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2E => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2F => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x30 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x31 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x32 => Ok(Self::EntityDestroy), + 0x33 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x34 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x35 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x36 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x37 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x38 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x39 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3A => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3B => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3C => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3D => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3E => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3F => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x40 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x41 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x42 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x43 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x44 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x45 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x46 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x47 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x48 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x49 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4A => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4B => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4C => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4D => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + notification: bool, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + notification, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_category: i32, + sound_id: i32, + parrotted_entity_type: String, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_category, + sound_id, + parrotted_entity_type, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PrepareCraftingGrid { + pub window_id: u8, + pub action_number: u16, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + pub type_: u32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + pub notification: bool, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub sound_id: i32, + pub parrotted_entity_type: String, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_17w15a/handshake.rs b/protocol/src/version/v_17w15a/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_17w15a/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_17w15a/login.rs b/protocol/src/version/v_17w15a/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_17w15a/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_17w15a/mod.rs b/protocol/src/version/v_17w15a/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_17w15a/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_17w15a/status.rs b/protocol/src/version/v_17w15a/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_17w15a/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_17w18b/game.rs b/protocol/src/version/v_17w18b/game.rs new file mode 100644 index 0000000..6bca036 --- /dev/null +++ b/protocol/src/version/v_17w18b/game.rs @@ -0,0 +1,2778 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + PrepareCraftingGrid(PrepareCraftingGrid), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::PrepareCraftingGrid(_) => 0x01, + Self::ServerBoundTabComplete(_) => 0x02, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0B, + Self::ServerBoundKeepAlive(_) => 0x0C, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x10, + Self::ServerBoundVehicleMove(_) => 0x11, + Self::SteerBoat(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x19, + Self::SetCreativeSlot(_) => 0x1A, + Self::UpdateSign(_) => 0x1B, + Self::ArmAnimation(_) => 0x1C, + Self::Spectate(_) => 0x1D, + Self::BlockPlace(_) => 0x1E, + Self::UseItem(_) => 0x1F, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let prepare_crafting_grid = PrepareCraftingGrid::decode(reader)?; + + Ok(Self::PrepareCraftingGrid(prepare_crafting_grid)) + } + 0x02 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0B => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0C => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x10 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x11 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x12 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x19 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1A => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1B => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1C => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1D => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1E => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1F => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn prepare_crafting_grid(window_id: u8, action_number: u16) -> Self { + let prepare_crafting_grid = PrepareCraftingGrid { + window_id, + action_number, + }; + + Self::PrepareCraftingGrid(prepare_crafting_grid) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: u32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x08, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete => 0x0F, + Self::ClientBoundChat(_) => 0x10, + Self::MultiBlockChange(_) => 0x11, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::JoinGame(_) => 0x24, + Self::Map(_) => 0x25, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x29, + Self::ClientBoundVehicleMove(_) => 0x2A, + Self::OpenSignEntity(_) => 0x2B, + Self::ClientBoundAbilities(_) => 0x2C, + Self::CombatEvent(_) => 0x2D, + Self::PlayerInfo(_) => 0x2E, + Self::ClientBoundPosition(_) => 0x2F, + Self::Bed(_) => 0x30, + Self::UnlockRecipes(_) => 0x31, + Self::EntityDestroy => 0x32, + Self::RemoveEntityEffect(_) => 0x33, + Self::ResourcePackSend(_) => 0x34, + Self::Respawn(_) => 0x35, + Self::EntityHeadRotation(_) => 0x36, + Self::WorldBorder(_) => 0x37, + Self::Camera(_) => 0x38, + Self::ClientBoundHeldItemSlot(_) => 0x39, + Self::ScoreboardDisplayObjective(_) => 0x3A, + Self::EntityMetadata(_) => 0x3B, + Self::AttachEntity(_) => 0x3C, + Self::EntityVelocity(_) => 0x3D, + Self::EntityEquipment(_) => 0x3E, + Self::Experience(_) => 0x3F, + Self::UpdateHealth(_) => 0x40, + Self::ScoreboardObjective(_) => 0x41, + Self::SetPassengers(_) => 0x42, + Self::Teams(_) => 0x43, + Self::ScoreboardScore(_) => 0x44, + Self::SpawnPosition(_) => 0x45, + Self::UpdateTime(_) => 0x46, + Self::Title(_) => 0x47, + Self::SoundEffect(_) => 0x48, + Self::PlayerlistHeader(_) => 0x49, + Self::Collect(_) => 0x4A, + Self::EntityTeleport(_) => 0x4B, + Self::EntityUpdateAttributes(_) => 0x4C, + Self::EntityEffect(_) => 0x4D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0F => Ok(Self::ClientBoundTabComplete), + 0x10 => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x11 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x29 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2A => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2B => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2C => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2D => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2E => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2F => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x30 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x31 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x32 => Ok(Self::EntityDestroy), + 0x33 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x34 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x35 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x36 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x37 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x38 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x39 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3A => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3B => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3C => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3D => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3E => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3F => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x40 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x41 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x42 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x43 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x44 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x45 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x46 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x47 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x48 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x49 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4A => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4B => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4C => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4D => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i16, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PrepareCraftingGrid { + pub window_id: u8, + pub action_number: u16, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + pub type_: u32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + pub action: i16, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_17w18b/handshake.rs b/protocol/src/version/v_17w18b/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_17w18b/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_17w18b/login.rs b/protocol/src/version/v_17w18b/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_17w18b/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_17w18b/mod.rs b/protocol/src/version/v_17w18b/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_17w18b/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_17w18b/status.rs b/protocol/src/version/v_17w18b/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_17w18b/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_17w50a/game.rs b/protocol/src/version/v_17w50a/game.rs new file mode 100644 index 0000000..c35d566 --- /dev/null +++ b/protocol/src/version/v_17w50a/game.rs @@ -0,0 +1,2917 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x04, + Self::ServerBoundChat(_) => 0x01, + Self::ClientCommand(_) => 0x02, + Self::Settings(_) => 0x03, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x0C, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::CraftRecipeRequest(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x1A, + Self::SetCreativeSlot(_) => 0x1B, + Self::UpdateSign(_) => 0x1C, + Self::ArmAnimation(_) => 0x1D, + Self::Spectate(_) => 0x1E, + Self::BlockPlace(_) => 0x1F, + Self::UseItem(_) => 0x20, + Self::AdvancementTab(_) => 0x19, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x04 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x01 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x02 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x03 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0C => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x1A => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1B => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1C => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1D => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1E => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1F => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x20 => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x19 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x4F, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::JoinGame(_) => 0x24, + Self::Map(_) => 0x25, + Self::RelEntityMove(_) => 0x27, + Self::EntityMoveLook(_) => 0x28, + Self::EntityLook(_) => 0x29, + Self::Entity(_) => 0x26, + Self::ClientBoundVehicleMove(_) => 0x2A, + Self::OpenSignEntity(_) => 0x2B, + Self::CraftRecipeResponse(_) => 0x2C, + Self::ClientBoundAbilities(_) => 0x2D, + Self::CombatEvent(_) => 0x2E, + Self::PlayerInfo(_) => 0x2F, + Self::ClientBoundPosition(_) => 0x30, + Self::Bed(_) => 0x31, + Self::UnlockRecipes(_) => 0x32, + Self::EntityDestroy => 0x33, + Self::RemoveEntityEffect(_) => 0x34, + Self::ResourcePackSend(_) => 0x35, + Self::Respawn(_) => 0x36, + Self::EntityHeadRotation(_) => 0x37, + Self::WorldBorder(_) => 0x39, + Self::Camera(_) => 0x3A, + Self::ClientBoundHeldItemSlot(_) => 0x3B, + Self::ScoreboardDisplayObjective(_) => 0x3C, + Self::EntityMetadata(_) => 0x3D, + Self::AttachEntity(_) => 0x3E, + Self::EntityVelocity(_) => 0x3F, + Self::EntityEquipment(_) => 0x40, + Self::Experience(_) => 0x41, + Self::UpdateHealth(_) => 0x42, + Self::ScoreboardObjective(_) => 0x43, + Self::SetPassengers(_) => 0x44, + Self::Teams(_) => 0x45, + Self::ScoreboardScore(_) => 0x46, + Self::SpawnPosition(_) => 0x47, + Self::UpdateTime(_) => 0x48, + Self::Title(_) => 0x49, + Self::StopSound(_) => 0x4A, + Self::SoundEffect(_) => 0x4B, + Self::PlayerlistHeader(_) => 0x4C, + Self::Collect(_) => 0x4D, + Self::EntityTeleport(_) => 0x4E, + Self::EntityUpdateAttributes(_) => 0x50, + Self::EntityEffect(_) => 0x51, + Self::SelectAdvancementTab(_) => 0x38, + Self::DeclareRecipes => 0x52, + Self::Tags(_) => 0x53, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x4F => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x28 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x29 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x26 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2A => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2B => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2C => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2D => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2E => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2F => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x30 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x31 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x32 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x33 => Ok(Self::EntityDestroy), + 0x34 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x35 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x36 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x37 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x39 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3A => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3B => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3C => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3D => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3E => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3F => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x40 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x41 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x42 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x43 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x44 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x45 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x46 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x47 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x48 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x49 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4A => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4B => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4C => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4D => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4E => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x50 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x51 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x38 => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x52 => Ok(Self::DeclareRecipes), + 0x53 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, +} diff --git a/protocol/src/version/v_17w50a/handshake.rs b/protocol/src/version/v_17w50a/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_17w50a/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_17w50a/login.rs b/protocol/src/version/v_17w50a/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_17w50a/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_17w50a/mod.rs b/protocol/src/version/v_17w50a/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_17w50a/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_17w50a/status.rs b/protocol/src/version/v_17w50a/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_17w50a/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_10/game.rs b/protocol/src/version/v_1_10/game.rs new file mode 100644 index 0000000..c9ee17b --- /dev/null +++ b/protocol/src/version/v_1_10/game.rs @@ -0,0 +1,2684 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_10/handshake.rs b/protocol/src/version/v_1_10/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_10/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_10/login.rs b/protocol/src/version/v_1_10/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_10/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_10/mod.rs b/protocol/src/version/v_1_10/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_10/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_10/status.rs b/protocol/src/version/v_1_10/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_10/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_10_pre1/game.rs b/protocol/src/version/v_1_10_pre1/game.rs new file mode 100644 index 0000000..c9ee17b --- /dev/null +++ b/protocol/src/version/v_1_10_pre1/game.rs @@ -0,0 +1,2684 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_10_pre1/handshake.rs b/protocol/src/version/v_1_10_pre1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_10_pre1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_10_pre1/login.rs b/protocol/src/version/v_1_10_pre1/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_10_pre1/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_10_pre1/mod.rs b/protocol/src/version/v_1_10_pre1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_10_pre1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_10_pre1/status.rs b/protocol/src/version/v_1_10_pre1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_10_pre1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_11/game.rs b/protocol/src/version/v_1_11/game.rs new file mode 100644 index 0000000..3dd337b --- /dev/null +++ b/protocol/src/version/v_1_11/game.rs @@ -0,0 +1,2692 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_11/handshake.rs b/protocol/src/version/v_1_11/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_11/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_11/login.rs b/protocol/src/version/v_1_11/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_11/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_11/mod.rs b/protocol/src/version/v_1_11/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_11/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_11/status.rs b/protocol/src/version/v_1_11/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_11/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_12/game.rs b/protocol/src/version/v_1_12/game.rs new file mode 100644 index 0000000..7b5e8a0 --- /dev/null +++ b/protocol/src/version/v_1_12/game.rs @@ -0,0 +1,2817 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + PrepareCraftingGrid(PrepareCraftingGrid), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::PrepareCraftingGrid(_) => 0x01, + Self::ServerBoundTabComplete(_) => 0x02, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0B, + Self::ServerBoundKeepAlive(_) => 0x0C, + Self::ServerBoundPosition(_) => 0x0E, + Self::PositionLook(_) => 0x0F, + Self::Look(_) => 0x10, + Self::Flying(_) => 0x0D, + Self::ServerBoundVehicleMove(_) => 0x11, + Self::SteerBoat(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x1A, + Self::SetCreativeSlot(_) => 0x1B, + Self::UpdateSign(_) => 0x1C, + Self::ArmAnimation(_) => 0x1D, + Self::Spectate(_) => 0x1E, + Self::BlockPlace(_) => 0x1F, + Self::UseItem(_) => 0x20, + Self::AdvancementTab(_) => 0x19, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let prepare_crafting_grid = PrepareCraftingGrid::decode(reader)?; + + Ok(Self::PrepareCraftingGrid(prepare_crafting_grid)) + } + 0x02 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0B => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0C => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0E => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0F => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x10 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0D => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x11 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x12 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x1A => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1B => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1C => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1D => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1E => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1F => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x20 => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x19 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn prepare_crafting_grid(window_id: u8, action_number: u16) -> Self { + let prepare_crafting_grid = PrepareCraftingGrid { + window_id, + action_number, + }; + + Self::PrepareCraftingGrid(prepare_crafting_grid) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x4C, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x25, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::UnlockRecipes(_) => 0x30, + Self::EntityDestroy => 0x31, + Self::RemoveEntityEffect(_) => 0x32, + Self::ResourcePackSend(_) => 0x33, + Self::Respawn(_) => 0x34, + Self::EntityHeadRotation(_) => 0x35, + Self::WorldBorder(_) => 0x37, + Self::Camera(_) => 0x38, + Self::ClientBoundHeldItemSlot(_) => 0x39, + Self::ScoreboardDisplayObjective(_) => 0x3A, + Self::EntityMetadata(_) => 0x3B, + Self::AttachEntity(_) => 0x3C, + Self::EntityVelocity(_) => 0x3D, + Self::EntityEquipment(_) => 0x3E, + Self::Experience(_) => 0x3F, + Self::UpdateHealth(_) => 0x40, + Self::ScoreboardObjective(_) => 0x41, + Self::SetPassengers(_) => 0x42, + Self::Teams(_) => 0x43, + Self::ScoreboardScore(_) => 0x44, + Self::SpawnPosition(_) => 0x45, + Self::UpdateTime(_) => 0x46, + Self::Title(_) => 0x47, + Self::SoundEffect(_) => 0x48, + Self::PlayerlistHeader(_) => 0x49, + Self::Collect(_) => 0x4A, + Self::EntityTeleport(_) => 0x4B, + Self::EntityUpdateAttributes(_) => 0x4D, + Self::EntityEffect(_) => 0x4E, + Self::SelectAdvancementTab(_) => 0x36, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x4C => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x25 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x31 => Ok(Self::EntityDestroy), + 0x32 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x33 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x34 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x35 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x37 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x38 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x39 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3A => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3B => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3C => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3D => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3E => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3F => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x40 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x41 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x42 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x43 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x44 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x45 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x46 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x47 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x48 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x49 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4A => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4B => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4D => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4E => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x36 => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PrepareCraftingGrid { + pub window_id: u8, + pub action_number: u16, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} diff --git a/protocol/src/version/v_1_12/handshake.rs b/protocol/src/version/v_1_12/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_12/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_12/login.rs b/protocol/src/version/v_1_12/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_12/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_12/mod.rs b/protocol/src/version/v_1_12/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_12/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_12/status.rs b/protocol/src/version/v_1_12/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_12/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_12_1/game.rs b/protocol/src/version/v_1_12_1/game.rs new file mode 100644 index 0000000..1612b90 --- /dev/null +++ b/protocol/src/version/v_1_12_1/game.rs @@ -0,0 +1,2840 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x0C, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::CraftRecipeRequest(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x1A, + Self::SetCreativeSlot(_) => 0x1B, + Self::UpdateSign(_) => 0x1C, + Self::ArmAnimation(_) => 0x1D, + Self::Spectate(_) => 0x1E, + Self::BlockPlace(_) => 0x1F, + Self::UseItem(_) => 0x20, + Self::AdvancementTab(_) => 0x19, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0C => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x1A => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1B => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1C => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1D => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1E => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1F => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x20 => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x19 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: i32, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x4D, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x25, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::CraftRecipeResponse(_) => 0x2B, + Self::ClientBoundAbilities(_) => 0x2C, + Self::CombatEvent(_) => 0x2D, + Self::PlayerInfo(_) => 0x2E, + Self::ClientBoundPosition(_) => 0x2F, + Self::Bed(_) => 0x30, + Self::UnlockRecipes(_) => 0x31, + Self::EntityDestroy => 0x32, + Self::RemoveEntityEffect(_) => 0x33, + Self::ResourcePackSend(_) => 0x34, + Self::Respawn(_) => 0x35, + Self::EntityHeadRotation(_) => 0x36, + Self::WorldBorder(_) => 0x38, + Self::Camera(_) => 0x39, + Self::ClientBoundHeldItemSlot(_) => 0x3A, + Self::ScoreboardDisplayObjective(_) => 0x3B, + Self::EntityMetadata(_) => 0x3C, + Self::AttachEntity(_) => 0x3D, + Self::EntityVelocity(_) => 0x3E, + Self::EntityEquipment(_) => 0x3F, + Self::Experience(_) => 0x40, + Self::UpdateHealth(_) => 0x41, + Self::ScoreboardObjective(_) => 0x42, + Self::SetPassengers(_) => 0x43, + Self::Teams(_) => 0x44, + Self::ScoreboardScore(_) => 0x45, + Self::SpawnPosition(_) => 0x46, + Self::UpdateTime(_) => 0x47, + Self::Title(_) => 0x48, + Self::SoundEffect(_) => 0x49, + Self::PlayerlistHeader(_) => 0x4A, + Self::Collect(_) => 0x4B, + Self::EntityTeleport(_) => 0x4C, + Self::EntityUpdateAttributes(_) => 0x4E, + Self::EntityEffect(_) => 0x4F, + Self::SelectAdvancementTab(_) => 0x37, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x4D => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x25 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2C => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2D => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2E => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2F => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x30 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x31 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x32 => Ok(Self::EntityDestroy), + 0x33 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x34 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x35 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x36 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x38 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x39 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3A => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3B => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3C => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3D => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3E => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3F => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x40 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x41 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x42 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x43 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x44 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x45 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x46 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x47 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x48 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x49 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4A => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4B => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4C => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4E => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4F => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x37 => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: i32) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + #[packet(with = "var_int")] + pub recipe: i32, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + #[packet(with = "var_int")] + pub recipe: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} diff --git a/protocol/src/version/v_1_12_1/handshake.rs b/protocol/src/version/v_1_12_1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_12_1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_12_1/login.rs b/protocol/src/version/v_1_12_1/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_12_1/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_12_1/mod.rs b/protocol/src/version/v_1_12_1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_12_1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_12_1/status.rs b/protocol/src/version/v_1_12_1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_12_1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_12_2/game.rs b/protocol/src/version/v_1_12_2/game.rs new file mode 100644 index 0000000..a94df04 --- /dev/null +++ b/protocol/src/version/v_1_12_2/game.rs @@ -0,0 +1,2838 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x0C, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::CraftRecipeRequest(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x1A, + Self::SetCreativeSlot(_) => 0x1B, + Self::UpdateSign(_) => 0x1C, + Self::ArmAnimation(_) => 0x1D, + Self::Spectate(_) => 0x1E, + Self::BlockPlace(_) => 0x1F, + Self::UseItem(_) => 0x20, + Self::AdvancementTab(_) => 0x19, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0C => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x1A => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1B => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1C => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1D => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1E => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1F => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x20 => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x19 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: i32, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x4D, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x25, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::CraftRecipeResponse(_) => 0x2B, + Self::ClientBoundAbilities(_) => 0x2C, + Self::CombatEvent(_) => 0x2D, + Self::PlayerInfo(_) => 0x2E, + Self::ClientBoundPosition(_) => 0x2F, + Self::Bed(_) => 0x30, + Self::UnlockRecipes(_) => 0x31, + Self::EntityDestroy => 0x32, + Self::RemoveEntityEffect(_) => 0x33, + Self::ResourcePackSend(_) => 0x34, + Self::Respawn(_) => 0x35, + Self::EntityHeadRotation(_) => 0x36, + Self::WorldBorder(_) => 0x38, + Self::Camera(_) => 0x39, + Self::ClientBoundHeldItemSlot(_) => 0x3A, + Self::ScoreboardDisplayObjective(_) => 0x3B, + Self::EntityMetadata(_) => 0x3C, + Self::AttachEntity(_) => 0x3D, + Self::EntityVelocity(_) => 0x3E, + Self::EntityEquipment(_) => 0x3F, + Self::Experience(_) => 0x40, + Self::UpdateHealth(_) => 0x41, + Self::ScoreboardObjective(_) => 0x42, + Self::SetPassengers(_) => 0x43, + Self::Teams(_) => 0x44, + Self::ScoreboardScore(_) => 0x45, + Self::SpawnPosition(_) => 0x46, + Self::UpdateTime(_) => 0x47, + Self::Title(_) => 0x48, + Self::SoundEffect(_) => 0x49, + Self::PlayerlistHeader(_) => 0x4A, + Self::Collect(_) => 0x4B, + Self::EntityTeleport(_) => 0x4C, + Self::EntityUpdateAttributes(_) => 0x4E, + Self::EntityEffect(_) => 0x4F, + Self::SelectAdvancementTab(_) => 0x37, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x4D => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x25 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2C => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2D => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2E => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2F => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x30 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x31 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x32 => Ok(Self::EntityDestroy), + 0x33 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x34 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x35 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x36 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x38 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x39 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3A => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3B => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3C => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3D => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3E => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3F => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x40 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x41 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x42 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x43 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x44 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x45 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x46 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x47 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x48 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x49 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4A => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4B => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4C => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4E => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4F => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x37 => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: i32) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + #[packet(with = "var_int")] + pub recipe: i32, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + #[packet(with = "var_int")] + pub recipe: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} diff --git a/protocol/src/version/v_1_12_2/handshake.rs b/protocol/src/version/v_1_12_2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_12_2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_12_2/login.rs b/protocol/src/version/v_1_12_2/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_12_2/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_12_2/mod.rs b/protocol/src/version/v_1_12_2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_12_2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_12_2/status.rs b/protocol/src/version/v_1_12_2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_12_2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_12_pre4/game.rs b/protocol/src/version/v_1_12_pre4/game.rs new file mode 100644 index 0000000..8ead441 --- /dev/null +++ b/protocol/src/version/v_1_12_pre4/game.rs @@ -0,0 +1,2815 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + PrepareCraftingGrid(PrepareCraftingGrid), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::PrepareCraftingGrid(_) => 0x01, + Self::ServerBoundTabComplete(_) => 0x02, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0B, + Self::ServerBoundKeepAlive(_) => 0x0C, + Self::ServerBoundPosition(_) => 0x0D, + Self::PositionLook(_) => 0x0E, + Self::Look(_) => 0x0F, + Self::Flying(_) => 0x10, + Self::ServerBoundVehicleMove(_) => 0x11, + Self::SteerBoat(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::BlockDig(_) => 0x14, + Self::EntityAction(_) => 0x15, + Self::SteerVehicle(_) => 0x16, + Self::CraftingBookData(_) => 0x17, + Self::ResourcePackReceive(_) => 0x18, + Self::ServerBoundHeldItemSlot(_) => 0x19, + Self::SetCreativeSlot(_) => 0x1A, + Self::UpdateSign(_) => 0x1B, + Self::ArmAnimation(_) => 0x1C, + Self::Spectate(_) => 0x1D, + Self::BlockPlace(_) => 0x1E, + Self::UseItem(_) => 0x1F, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let prepare_crafting_grid = PrepareCraftingGrid::decode(reader)?; + + Ok(Self::PrepareCraftingGrid(prepare_crafting_grid)) + } + 0x02 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0B => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0C => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0D => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0E => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0F => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x10 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x11 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x12 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x15 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x16 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x17 => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x18 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x19 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x1A => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x1B => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1C => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1D => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1E => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1F => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn prepare_crafting_grid(window_id: u8, action_number: u16) -> Self { + let prepare_crafting_grid = PrepareCraftingGrid { + window_id, + action_number, + }; + + Self::PrepareCraftingGrid(prepare_crafting_grid) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: u32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + AdvancementProgress(AdvancementProgress), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x08, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete => 0x0F, + Self::ClientBoundChat(_) => 0x10, + Self::MultiBlockChange(_) => 0x11, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::JoinGame(_) => 0x24, + Self::Map(_) => 0x25, + Self::RelEntityMove(_) => 0x26, + Self::EntityMoveLook(_) => 0x27, + Self::EntityLook(_) => 0x28, + Self::Entity(_) => 0x29, + Self::ClientBoundVehicleMove(_) => 0x2A, + Self::OpenSignEntity(_) => 0x2B, + Self::ClientBoundAbilities(_) => 0x2C, + Self::CombatEvent(_) => 0x2D, + Self::PlayerInfo(_) => 0x2E, + Self::ClientBoundPosition(_) => 0x2F, + Self::Bed(_) => 0x30, + Self::UnlockRecipes(_) => 0x31, + Self::EntityDestroy => 0x32, + Self::RemoveEntityEffect(_) => 0x33, + Self::ResourcePackSend(_) => 0x34, + Self::Respawn(_) => 0x35, + Self::EntityHeadRotation(_) => 0x36, + Self::WorldBorder(_) => 0x37, + Self::Camera(_) => 0x38, + Self::ClientBoundHeldItemSlot(_) => 0x39, + Self::ScoreboardDisplayObjective(_) => 0x3A, + Self::EntityMetadata(_) => 0x3B, + Self::AttachEntity(_) => 0x3C, + Self::EntityVelocity(_) => 0x3D, + Self::EntityEquipment(_) => 0x3E, + Self::Experience(_) => 0x3F, + Self::UpdateHealth(_) => 0x40, + Self::ScoreboardObjective(_) => 0x41, + Self::SetPassengers(_) => 0x42, + Self::Teams(_) => 0x43, + Self::ScoreboardScore(_) => 0x44, + Self::SpawnPosition(_) => 0x45, + Self::UpdateTime(_) => 0x46, + Self::Title(_) => 0x47, + Self::SoundEffect(_) => 0x48, + Self::PlayerlistHeader(_) => 0x49, + Self::Collect(_) => 0x4A, + Self::EntityTeleport(_) => 0x4B, + Self::EntityUpdateAttributes(_) => 0x4C, + Self::EntityEffect(_) => 0x4D, + Self::AdvancementProgress(_) => 0x4E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0F => Ok(Self::ClientBoundTabComplete), + 0x10 => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x11 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x27 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x28 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x29 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2A => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2B => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2C => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2D => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2E => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2F => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x30 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x31 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x32 => Ok(Self::EntityDestroy), + 0x33 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x34 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x35 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x36 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x37 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x38 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x39 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3A => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3B => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3C => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3D => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3E => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3F => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x40 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x41 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x42 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x43 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x44 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x45 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x46 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x47 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x48 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x49 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4A => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4B => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4C => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4D => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x4E => { + let advancement_progress = AdvancementProgress::decode(reader)?; + + Ok(Self::AdvancementProgress(advancement_progress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i16, + crafting_book_open: bool, + filtering_craftable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn advancement_progress(id: String) -> Self { + let advancement_progress = AdvancementProgress { id }; + + Self::AdvancementProgress(advancement_progress) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PrepareCraftingGrid { + pub window_id: u8, + pub action_number: u16, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + pub type_: u32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + pub action: i16, + pub crafting_book_open: bool, + pub filtering_craftable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct AdvancementProgress { + pub id: String, +} diff --git a/protocol/src/version/v_1_12_pre4/handshake.rs b/protocol/src/version/v_1_12_pre4/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_12_pre4/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_12_pre4/login.rs b/protocol/src/version/v_1_12_pre4/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_12_pre4/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_12_pre4/mod.rs b/protocol/src/version/v_1_12_pre4/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_12_pre4/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_12_pre4/status.rs b/protocol/src/version/v_1_12_pre4/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_12_pre4/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_13/game.rs b/protocol/src/version/v_1_13/game.rs new file mode 100644 index 0000000..7a325a6 --- /dev/null +++ b/protocol/src/version/v_1_13/game.rs @@ -0,0 +1,3257 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::EditBook(_) => 0x0B, + Self::QueryEntityNbt(_) => 0x0C, + Self::PickItem(_) => 0x15, + Self::NameItem(_) => 0x1C, + Self::SelectTrade(_) => 0x1F, + Self::SetBeaconEffect(_) => 0x20, + Self::UpdateCommandBlock(_) => 0x22, + Self::UpdateCommandBlockMinecart(_) => 0x23, + Self::UpdateStructureBlock(_) => 0x25, + Self::ServerBoundTabComplete(_) => 0x05, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0D, + Self::ServerBoundKeepAlive(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x10, + Self::PositionLook(_) => 0x11, + Self::Look(_) => 0x12, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x13, + Self::SteerBoat(_) => 0x14, + Self::CraftRecipeRequest(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x17, + Self::BlockDig(_) => 0x18, + Self::EntityAction(_) => 0x19, + Self::SteerVehicle(_) => 0x1A, + Self::CraftingBookData(_) => 0x1B, + Self::ResourcePackReceive(_) => 0x1D, + Self::ServerBoundHeldItemSlot(_) => 0x21, + Self::SetCreativeSlot(_) => 0x24, + Self::UpdateSign(_) => 0x26, + Self::ArmAnimation(_) => 0x27, + Self::Spectate(_) => 0x28, + Self::BlockPlace(_) => 0x29, + Self::UseItem(_) => 0x2A, + Self::AdvancementTab(_) => 0x1E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x0B => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0C => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x15 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1C => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x1F => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x20 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x22 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x23 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x25 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x05 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0D => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x11 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x12 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x13 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x14 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x16 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x17 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x18 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1A => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1B => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1D => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x21 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x24 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x26 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x27 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x28 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x29 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x1E => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn edit_book(new_book: Option, signing: bool) -> Self { + let edit_book = EditBook { new_book, signing }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x51, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x31, + Self::NbtQueryResponse(_) => 0x1D, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1E, + Self::UnloadChunk(_) => 0x1F, + Self::GameStateChange(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x27, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenSignEntity(_) => 0x2C, + Self::CraftRecipeResponse(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2E, + Self::CombatEvent(_) => 0x2F, + Self::PlayerInfo(_) => 0x30, + Self::ClientBoundPosition(_) => 0x32, + Self::Bed(_) => 0x33, + Self::UnlockRecipes(_) => 0x34, + Self::EntityDestroy => 0x35, + Self::RemoveEntityEffect(_) => 0x36, + Self::ResourcePackSend(_) => 0x37, + Self::Respawn(_) => 0x38, + Self::EntityHeadRotation(_) => 0x39, + Self::WorldBorder(_) => 0x3B, + Self::Camera(_) => 0x3C, + Self::ClientBoundHeldItemSlot(_) => 0x3D, + Self::ScoreboardDisplayObjective(_) => 0x3E, + Self::EntityMetadata(_) => 0x3F, + Self::AttachEntity(_) => 0x40, + Self::EntityVelocity(_) => 0x41, + Self::EntityEquipment(_) => 0x42, + Self::Experience(_) => 0x43, + Self::UpdateHealth(_) => 0x44, + Self::ScoreboardObjective(_) => 0x45, + Self::SetPassengers(_) => 0x46, + Self::Teams(_) => 0x47, + Self::ScoreboardScore(_) => 0x48, + Self::SpawnPosition(_) => 0x49, + Self::UpdateTime(_) => 0x4A, + Self::Title(_) => 0x4B, + Self::StopSound(_) => 0x4C, + Self::SoundEffect(_) => 0x4D, + Self::PlayerlistHeader(_) => 0x4E, + Self::Collect(_) => 0x4F, + Self::EntityTeleport(_) => 0x50, + Self::EntityUpdateAttributes(_) => 0x52, + Self::EntityEffect(_) => 0x53, + Self::SelectAdvancementTab(_) => 0x3A, + Self::DeclareRecipes => 0x54, + Self::Tags(_) => 0x55, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x51 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x31 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x1D => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1E => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1F => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x20 => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2D => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2E => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2F => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x30 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x32 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x33 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x34 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x35 => Ok(Self::EntityDestroy), + 0x36 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x37 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x38 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x39 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3B => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3C => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3D => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3E => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3F => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x40 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x41 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x42 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x43 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x44 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x45 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x46 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x47 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x48 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x49 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4A => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4B => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4C => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4D => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4E => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4F => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x50 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x52 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x53 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3A => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x54 => Ok(Self::DeclareRecipes), + 0x55 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap, fluid_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_13/handshake.rs b/protocol/src/version/v_1_13/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_13/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_13/login.rs b/protocol/src/version/v_1_13/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_13/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_13/mod.rs b/protocol/src/version/v_1_13/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_13/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_13/status.rs b/protocol/src/version/v_1_13/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_13/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_13_1/game.rs b/protocol/src/version/v_1_13_1/game.rs new file mode 100644 index 0000000..396a73f --- /dev/null +++ b/protocol/src/version/v_1_13_1/game.rs @@ -0,0 +1,3263 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::EditBook(_) => 0x0B, + Self::QueryEntityNbt(_) => 0x0C, + Self::PickItem(_) => 0x15, + Self::NameItem(_) => 0x1C, + Self::SelectTrade(_) => 0x1F, + Self::SetBeaconEffect(_) => 0x20, + Self::UpdateCommandBlock(_) => 0x22, + Self::UpdateCommandBlockMinecart(_) => 0x23, + Self::UpdateStructureBlock(_) => 0x25, + Self::ServerBoundTabComplete(_) => 0x05, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0D, + Self::ServerBoundKeepAlive(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x10, + Self::PositionLook(_) => 0x11, + Self::Look(_) => 0x12, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x13, + Self::SteerBoat(_) => 0x14, + Self::CraftRecipeRequest(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x17, + Self::BlockDig(_) => 0x18, + Self::EntityAction(_) => 0x19, + Self::SteerVehicle(_) => 0x1A, + Self::CraftingBookData(_) => 0x1B, + Self::ResourcePackReceive(_) => 0x1D, + Self::ServerBoundHeldItemSlot(_) => 0x21, + Self::SetCreativeSlot(_) => 0x24, + Self::UpdateSign(_) => 0x26, + Self::ArmAnimation(_) => 0x27, + Self::Spectate(_) => 0x28, + Self::BlockPlace(_) => 0x29, + Self::UseItem(_) => 0x2A, + Self::AdvancementTab(_) => 0x1E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x0B => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0C => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x15 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1C => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x1F => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x20 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x22 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x23 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x25 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x05 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0D => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x11 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x12 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x13 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x14 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x16 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x17 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x18 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1A => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1B => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1D => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x21 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x24 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x26 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x27 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x28 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x29 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x1E => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x51, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x31, + Self::NbtQueryResponse(_) => 0x1D, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1E, + Self::UnloadChunk(_) => 0x1F, + Self::GameStateChange(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x27, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenSignEntity(_) => 0x2C, + Self::CraftRecipeResponse(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2E, + Self::CombatEvent(_) => 0x2F, + Self::PlayerInfo(_) => 0x30, + Self::ClientBoundPosition(_) => 0x32, + Self::Bed(_) => 0x33, + Self::UnlockRecipes(_) => 0x34, + Self::EntityDestroy => 0x35, + Self::RemoveEntityEffect(_) => 0x36, + Self::ResourcePackSend(_) => 0x37, + Self::Respawn(_) => 0x38, + Self::EntityHeadRotation(_) => 0x39, + Self::WorldBorder(_) => 0x3B, + Self::Camera(_) => 0x3C, + Self::ClientBoundHeldItemSlot(_) => 0x3D, + Self::ScoreboardDisplayObjective(_) => 0x3E, + Self::EntityMetadata(_) => 0x3F, + Self::AttachEntity(_) => 0x40, + Self::EntityVelocity(_) => 0x41, + Self::EntityEquipment(_) => 0x42, + Self::Experience(_) => 0x43, + Self::UpdateHealth(_) => 0x44, + Self::ScoreboardObjective(_) => 0x45, + Self::SetPassengers(_) => 0x46, + Self::Teams(_) => 0x47, + Self::ScoreboardScore(_) => 0x48, + Self::SpawnPosition(_) => 0x49, + Self::UpdateTime(_) => 0x4A, + Self::Title(_) => 0x4B, + Self::StopSound(_) => 0x4C, + Self::SoundEffect(_) => 0x4D, + Self::PlayerlistHeader(_) => 0x4E, + Self::Collect(_) => 0x4F, + Self::EntityTeleport(_) => 0x50, + Self::EntityUpdateAttributes(_) => 0x52, + Self::EntityEffect(_) => 0x53, + Self::SelectAdvancementTab(_) => 0x3A, + Self::DeclareRecipes => 0x54, + Self::Tags(_) => 0x55, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x51 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x31 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x1D => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1E => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1F => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x20 => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2D => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2E => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2F => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x30 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x32 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x33 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x34 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x35 => Ok(Self::EntityDestroy), + 0x36 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x37 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x38 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x39 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3B => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3C => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3D => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3E => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3F => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x40 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x41 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x42 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x43 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x44 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x45 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x46 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x47 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x48 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x49 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4A => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4B => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4C => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4D => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4E => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4F => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x50 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x52 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x53 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3A => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x54 => Ok(Self::DeclareRecipes), + 0x55 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap, fluid_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_13_1/handshake.rs b/protocol/src/version/v_1_13_1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_13_1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_13_1/login.rs b/protocol/src/version/v_1_13_1/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_13_1/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_13_1/mod.rs b/protocol/src/version/v_1_13_1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_13_1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_13_1/status.rs b/protocol/src/version/v_1_13_1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_13_1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_13_2/game.rs b/protocol/src/version/v_1_13_2/game.rs new file mode 100644 index 0000000..396a73f --- /dev/null +++ b/protocol/src/version/v_1_13_2/game.rs @@ -0,0 +1,3263 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::EditBook(_) => 0x0B, + Self::QueryEntityNbt(_) => 0x0C, + Self::PickItem(_) => 0x15, + Self::NameItem(_) => 0x1C, + Self::SelectTrade(_) => 0x1F, + Self::SetBeaconEffect(_) => 0x20, + Self::UpdateCommandBlock(_) => 0x22, + Self::UpdateCommandBlockMinecart(_) => 0x23, + Self::UpdateStructureBlock(_) => 0x25, + Self::ServerBoundTabComplete(_) => 0x05, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0D, + Self::ServerBoundKeepAlive(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x10, + Self::PositionLook(_) => 0x11, + Self::Look(_) => 0x12, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x13, + Self::SteerBoat(_) => 0x14, + Self::CraftRecipeRequest(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x17, + Self::BlockDig(_) => 0x18, + Self::EntityAction(_) => 0x19, + Self::SteerVehicle(_) => 0x1A, + Self::CraftingBookData(_) => 0x1B, + Self::ResourcePackReceive(_) => 0x1D, + Self::ServerBoundHeldItemSlot(_) => 0x21, + Self::SetCreativeSlot(_) => 0x24, + Self::UpdateSign(_) => 0x26, + Self::ArmAnimation(_) => 0x27, + Self::Spectate(_) => 0x28, + Self::BlockPlace(_) => 0x29, + Self::UseItem(_) => 0x2A, + Self::AdvancementTab(_) => 0x1E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x0B => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0C => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x15 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1C => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x1F => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x20 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x22 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x23 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x25 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x05 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0D => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x11 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x12 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x13 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x14 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x16 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x17 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x18 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1A => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1B => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1D => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x21 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x24 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x26 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x27 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x28 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x29 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x1E => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x51, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x31, + Self::NbtQueryResponse(_) => 0x1D, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1E, + Self::UnloadChunk(_) => 0x1F, + Self::GameStateChange(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x27, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenSignEntity(_) => 0x2C, + Self::CraftRecipeResponse(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2E, + Self::CombatEvent(_) => 0x2F, + Self::PlayerInfo(_) => 0x30, + Self::ClientBoundPosition(_) => 0x32, + Self::Bed(_) => 0x33, + Self::UnlockRecipes(_) => 0x34, + Self::EntityDestroy => 0x35, + Self::RemoveEntityEffect(_) => 0x36, + Self::ResourcePackSend(_) => 0x37, + Self::Respawn(_) => 0x38, + Self::EntityHeadRotation(_) => 0x39, + Self::WorldBorder(_) => 0x3B, + Self::Camera(_) => 0x3C, + Self::ClientBoundHeldItemSlot(_) => 0x3D, + Self::ScoreboardDisplayObjective(_) => 0x3E, + Self::EntityMetadata(_) => 0x3F, + Self::AttachEntity(_) => 0x40, + Self::EntityVelocity(_) => 0x41, + Self::EntityEquipment(_) => 0x42, + Self::Experience(_) => 0x43, + Self::UpdateHealth(_) => 0x44, + Self::ScoreboardObjective(_) => 0x45, + Self::SetPassengers(_) => 0x46, + Self::Teams(_) => 0x47, + Self::ScoreboardScore(_) => 0x48, + Self::SpawnPosition(_) => 0x49, + Self::UpdateTime(_) => 0x4A, + Self::Title(_) => 0x4B, + Self::StopSound(_) => 0x4C, + Self::SoundEffect(_) => 0x4D, + Self::PlayerlistHeader(_) => 0x4E, + Self::Collect(_) => 0x4F, + Self::EntityTeleport(_) => 0x50, + Self::EntityUpdateAttributes(_) => 0x52, + Self::EntityEffect(_) => 0x53, + Self::SelectAdvancementTab(_) => 0x3A, + Self::DeclareRecipes => 0x54, + Self::Tags(_) => 0x55, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x51 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x31 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x1D => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1E => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1F => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x20 => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2D => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2E => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2F => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x30 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x32 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x33 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x34 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x35 => Ok(Self::EntityDestroy), + 0x36 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x37 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x38 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x39 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3B => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3C => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3D => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3E => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3F => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x40 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x41 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x42 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x43 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x44 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x45 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x46 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x47 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x48 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x49 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4A => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4B => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4C => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4D => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4E => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4F => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x50 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x52 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x53 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3A => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x54 => Ok(Self::DeclareRecipes), + 0x55 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap, fluid_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_13_2/handshake.rs b/protocol/src/version/v_1_13_2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_13_2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_13_2/login.rs b/protocol/src/version/v_1_13_2/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_13_2/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_13_2/mod.rs b/protocol/src/version/v_1_13_2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_13_2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_13_2/status.rs b/protocol/src/version/v_1_13_2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_13_2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_13_2_pre1/game.rs b/protocol/src/version/v_1_13_2_pre1/game.rs new file mode 100644 index 0000000..396a73f --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre1/game.rs @@ -0,0 +1,3263 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::EditBook(_) => 0x0B, + Self::QueryEntityNbt(_) => 0x0C, + Self::PickItem(_) => 0x15, + Self::NameItem(_) => 0x1C, + Self::SelectTrade(_) => 0x1F, + Self::SetBeaconEffect(_) => 0x20, + Self::UpdateCommandBlock(_) => 0x22, + Self::UpdateCommandBlockMinecart(_) => 0x23, + Self::UpdateStructureBlock(_) => 0x25, + Self::ServerBoundTabComplete(_) => 0x05, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0D, + Self::ServerBoundKeepAlive(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x10, + Self::PositionLook(_) => 0x11, + Self::Look(_) => 0x12, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x13, + Self::SteerBoat(_) => 0x14, + Self::CraftRecipeRequest(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x17, + Self::BlockDig(_) => 0x18, + Self::EntityAction(_) => 0x19, + Self::SteerVehicle(_) => 0x1A, + Self::CraftingBookData(_) => 0x1B, + Self::ResourcePackReceive(_) => 0x1D, + Self::ServerBoundHeldItemSlot(_) => 0x21, + Self::SetCreativeSlot(_) => 0x24, + Self::UpdateSign(_) => 0x26, + Self::ArmAnimation(_) => 0x27, + Self::Spectate(_) => 0x28, + Self::BlockPlace(_) => 0x29, + Self::UseItem(_) => 0x2A, + Self::AdvancementTab(_) => 0x1E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x0B => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0C => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x15 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1C => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x1F => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x20 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x22 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x23 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x25 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x05 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0D => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x11 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x12 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x13 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x14 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x16 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x17 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x18 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1A => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1B => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1D => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x21 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x24 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x26 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x27 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x28 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x29 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x1E => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x51, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x31, + Self::NbtQueryResponse(_) => 0x1D, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1E, + Self::UnloadChunk(_) => 0x1F, + Self::GameStateChange(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x27, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenSignEntity(_) => 0x2C, + Self::CraftRecipeResponse(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2E, + Self::CombatEvent(_) => 0x2F, + Self::PlayerInfo(_) => 0x30, + Self::ClientBoundPosition(_) => 0x32, + Self::Bed(_) => 0x33, + Self::UnlockRecipes(_) => 0x34, + Self::EntityDestroy => 0x35, + Self::RemoveEntityEffect(_) => 0x36, + Self::ResourcePackSend(_) => 0x37, + Self::Respawn(_) => 0x38, + Self::EntityHeadRotation(_) => 0x39, + Self::WorldBorder(_) => 0x3B, + Self::Camera(_) => 0x3C, + Self::ClientBoundHeldItemSlot(_) => 0x3D, + Self::ScoreboardDisplayObjective(_) => 0x3E, + Self::EntityMetadata(_) => 0x3F, + Self::AttachEntity(_) => 0x40, + Self::EntityVelocity(_) => 0x41, + Self::EntityEquipment(_) => 0x42, + Self::Experience(_) => 0x43, + Self::UpdateHealth(_) => 0x44, + Self::ScoreboardObjective(_) => 0x45, + Self::SetPassengers(_) => 0x46, + Self::Teams(_) => 0x47, + Self::ScoreboardScore(_) => 0x48, + Self::SpawnPosition(_) => 0x49, + Self::UpdateTime(_) => 0x4A, + Self::Title(_) => 0x4B, + Self::StopSound(_) => 0x4C, + Self::SoundEffect(_) => 0x4D, + Self::PlayerlistHeader(_) => 0x4E, + Self::Collect(_) => 0x4F, + Self::EntityTeleport(_) => 0x50, + Self::EntityUpdateAttributes(_) => 0x52, + Self::EntityEffect(_) => 0x53, + Self::SelectAdvancementTab(_) => 0x3A, + Self::DeclareRecipes => 0x54, + Self::Tags(_) => 0x55, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x51 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x31 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x1D => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1E => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1F => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x20 => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2D => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2E => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2F => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x30 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x32 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x33 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x34 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x35 => Ok(Self::EntityDestroy), + 0x36 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x37 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x38 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x39 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3B => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3C => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3D => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3E => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3F => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x40 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x41 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x42 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x43 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x44 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x45 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x46 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x47 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x48 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x49 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4A => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4B => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4C => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4D => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4E => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4F => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x50 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x52 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x53 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3A => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x54 => Ok(Self::DeclareRecipes), + 0x55 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap, fluid_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_13_2_pre1/handshake.rs b/protocol/src/version/v_1_13_2_pre1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_13_2_pre1/login.rs b/protocol/src/version/v_1_13_2_pre1/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre1/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_13_2_pre1/mod.rs b/protocol/src/version/v_1_13_2_pre1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_13_2_pre1/status.rs b/protocol/src/version/v_1_13_2_pre1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_13_2_pre2/game.rs b/protocol/src/version/v_1_13_2_pre2/game.rs new file mode 100644 index 0000000..396a73f --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre2/game.rs @@ -0,0 +1,3263 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::EditBook(_) => 0x0B, + Self::QueryEntityNbt(_) => 0x0C, + Self::PickItem(_) => 0x15, + Self::NameItem(_) => 0x1C, + Self::SelectTrade(_) => 0x1F, + Self::SetBeaconEffect(_) => 0x20, + Self::UpdateCommandBlock(_) => 0x22, + Self::UpdateCommandBlockMinecart(_) => 0x23, + Self::UpdateStructureBlock(_) => 0x25, + Self::ServerBoundTabComplete(_) => 0x05, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x06, + Self::EnchantItem(_) => 0x07, + Self::WindowClick(_) => 0x08, + Self::ServerBoundCloseWindow(_) => 0x09, + Self::ServerBoundCustomPayload(_) => 0x0A, + Self::UseEntity(_) => 0x0D, + Self::ServerBoundKeepAlive(_) => 0x0E, + Self::ServerBoundPosition(_) => 0x10, + Self::PositionLook(_) => 0x11, + Self::Look(_) => 0x12, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x13, + Self::SteerBoat(_) => 0x14, + Self::CraftRecipeRequest(_) => 0x16, + Self::ServerBoundAbilities(_) => 0x17, + Self::BlockDig(_) => 0x18, + Self::EntityAction(_) => 0x19, + Self::SteerVehicle(_) => 0x1A, + Self::CraftingBookData(_) => 0x1B, + Self::ResourcePackReceive(_) => 0x1D, + Self::ServerBoundHeldItemSlot(_) => 0x21, + Self::SetCreativeSlot(_) => 0x24, + Self::UpdateSign(_) => 0x26, + Self::ArmAnimation(_) => 0x27, + Self::Spectate(_) => 0x28, + Self::BlockPlace(_) => 0x29, + Self::UseItem(_) => 0x2A, + Self::AdvancementTab(_) => 0x1E, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x0B => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0C => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x15 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1C => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x1F => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x20 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x22 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x23 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x25 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x05 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x06 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x07 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x08 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x09 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0A => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0D => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0E => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x11 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x12 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x13 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x14 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x16 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x17 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x18 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x19 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1A => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1B => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1D => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x21 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x24 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x26 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x27 => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x28 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x29 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2A => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x1E => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x51, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x31, + Self::NbtQueryResponse(_) => 0x1D, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x14, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1E, + Self::UnloadChunk(_) => 0x1F, + Self::GameStateChange(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x27, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenSignEntity(_) => 0x2C, + Self::CraftRecipeResponse(_) => 0x2D, + Self::ClientBoundAbilities(_) => 0x2E, + Self::CombatEvent(_) => 0x2F, + Self::PlayerInfo(_) => 0x30, + Self::ClientBoundPosition(_) => 0x32, + Self::Bed(_) => 0x33, + Self::UnlockRecipes(_) => 0x34, + Self::EntityDestroy => 0x35, + Self::RemoveEntityEffect(_) => 0x36, + Self::ResourcePackSend(_) => 0x37, + Self::Respawn(_) => 0x38, + Self::EntityHeadRotation(_) => 0x39, + Self::WorldBorder(_) => 0x3B, + Self::Camera(_) => 0x3C, + Self::ClientBoundHeldItemSlot(_) => 0x3D, + Self::ScoreboardDisplayObjective(_) => 0x3E, + Self::EntityMetadata(_) => 0x3F, + Self::AttachEntity(_) => 0x40, + Self::EntityVelocity(_) => 0x41, + Self::EntityEquipment(_) => 0x42, + Self::Experience(_) => 0x43, + Self::UpdateHealth(_) => 0x44, + Self::ScoreboardObjective(_) => 0x45, + Self::SetPassengers(_) => 0x46, + Self::Teams(_) => 0x47, + Self::ScoreboardScore(_) => 0x48, + Self::SpawnPosition(_) => 0x49, + Self::UpdateTime(_) => 0x4A, + Self::Title(_) => 0x4B, + Self::StopSound(_) => 0x4C, + Self::SoundEffect(_) => 0x4D, + Self::PlayerlistHeader(_) => 0x4E, + Self::Collect(_) => 0x4F, + Self::EntityTeleport(_) => 0x50, + Self::EntityUpdateAttributes(_) => 0x52, + Self::EntityEffect(_) => 0x53, + Self::SelectAdvancementTab(_) => 0x3A, + Self::DeclareRecipes => 0x54, + Self::Tags(_) => 0x55, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x51 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x31 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x1D => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x14 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1E => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1F => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x20 => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x27 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2D => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x2E => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2F => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x30 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x32 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x33 => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x34 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x35 => Ok(Self::EntityDestroy), + 0x36 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x37 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x38 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x39 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3B => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3C => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3D => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x3E => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3F => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x40 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x41 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x42 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x43 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x44 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x45 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x46 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x47 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x48 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x49 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4A => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4B => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x4C => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x4D => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x4E => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x4F => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x50 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x52 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x53 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3A => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x54 => Ok(Self::DeclareRecipes), + 0x55 => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags(block_tags: TagsMap, item_tags: TagsMap, fluid_tags: TagsMap) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_13_2_pre2/handshake.rs b/protocol/src/version/v_1_13_2_pre2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_13_2_pre2/login.rs b/protocol/src/version/v_1_13_2_pre2/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre2/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_13_2_pre2/mod.rs b/protocol/src/version/v_1_13_2_pre2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_13_2_pre2/status.rs b/protocol/src/version/v_1_13_2_pre2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_13_2_pre2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_14/game.rs b/protocol/src/version/v_1_14/game.rs new file mode 100644 index 0000000..ed76c79 --- /dev/null +++ b/protocol/src/version/v_1_14/game.rs @@ -0,0 +1,3535 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x42, + Self::EntityMetadata(_) => 0x43, + Self::AttachEntity(_) => 0x44, + Self::EntityVelocity(_) => 0x45, + Self::EntityEquipment(_) => 0x46, + Self::Experience(_) => 0x47, + Self::UpdateHealth(_) => 0x48, + Self::ScoreboardObjective(_) => 0x49, + Self::SetPassengers(_) => 0x4A, + Self::Teams(_) => 0x4B, + Self::ScoreboardScore(_) => 0x4C, + Self::SpawnPosition(_) => 0x4D, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x42 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x43 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x44 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x45 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x46 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x47 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x48 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x49 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4A => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4B => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4C => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4D => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + max_players, + level_type, + view_distance, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_14/handshake.rs b/protocol/src/version/v_1_14/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_14/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_14/login.rs b/protocol/src/version/v_1_14/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_14/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_14/mod.rs b/protocol/src/version/v_1_14/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_14/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_14/status.rs b/protocol/src/version/v_1_14/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_14/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_14_1/game.rs b/protocol/src/version/v_1_14_1/game.rs new file mode 100644 index 0000000..ed76c79 --- /dev/null +++ b/protocol/src/version/v_1_14_1/game.rs @@ -0,0 +1,3535 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x42, + Self::EntityMetadata(_) => 0x43, + Self::AttachEntity(_) => 0x44, + Self::EntityVelocity(_) => 0x45, + Self::EntityEquipment(_) => 0x46, + Self::Experience(_) => 0x47, + Self::UpdateHealth(_) => 0x48, + Self::ScoreboardObjective(_) => 0x49, + Self::SetPassengers(_) => 0x4A, + Self::Teams(_) => 0x4B, + Self::ScoreboardScore(_) => 0x4C, + Self::SpawnPosition(_) => 0x4D, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x42 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x43 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x44 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x45 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x46 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x47 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x48 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x49 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4A => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4B => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4C => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4D => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + max_players, + level_type, + view_distance, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_14_1/handshake.rs b/protocol/src/version/v_1_14_1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_14_1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_14_1/login.rs b/protocol/src/version/v_1_14_1/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_14_1/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_14_1/mod.rs b/protocol/src/version/v_1_14_1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_14_1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_14_1/status.rs b/protocol/src/version/v_1_14_1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_14_1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_14_3/game.rs b/protocol/src/version/v_1_14_3/game.rs new file mode 100644 index 0000000..1901a5a --- /dev/null +++ b/protocol/src/version/v_1_14_3/game.rs @@ -0,0 +1,3538 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x42, + Self::EntityMetadata(_) => 0x43, + Self::AttachEntity(_) => 0x44, + Self::EntityVelocity(_) => 0x45, + Self::EntityEquipment(_) => 0x46, + Self::Experience(_) => 0x47, + Self::UpdateHealth(_) => 0x48, + Self::ScoreboardObjective(_) => 0x49, + Self::SetPassengers(_) => 0x4A, + Self::Teams(_) => 0x4B, + Self::ScoreboardScore(_) => 0x4C, + Self::SpawnPosition(_) => 0x4D, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x42 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x43 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x44 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x45 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x46 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x47 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x48 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x49 => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4A => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4B => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4C => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4D => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + max_players, + level_type, + view_distance, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} diff --git a/protocol/src/version/v_1_14_3/handshake.rs b/protocol/src/version/v_1_14_3/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_14_3/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_14_3/login.rs b/protocol/src/version/v_1_14_3/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_14_3/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_14_3/mod.rs b/protocol/src/version/v_1_14_3/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_14_3/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_14_3/status.rs b/protocol/src/version/v_1_14_3/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_14_3/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/packet/game.rs b/protocol/src/version/v_1_14_4/game.rs similarity index 99% rename from protocol/src/packet/game.rs rename to protocol/src/version/v_1_14_4/game.rs index cb6dc25..2d4d90e 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/version/v_1_14_4/game.rs @@ -1,15 +1,15 @@ // This file is automatically generated. // It is not intended for manual editing. -use crate::data::chat::Message; -use crate::data::game::*; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; -use nbt::CompoundTag; use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; use uuid::Uuid; -pub enum GameServerBoundPacket { +pub enum ServerBoundGamePacket { TeleportConfirm(TeleportConfirm), QueryBlockNbt(QueryBlockNbt), SetDifficulty(SetDifficulty), @@ -58,7 +58,7 @@ pub enum GameServerBoundPacket { AdvancementTab(AdvancementTab), } -impl GameServerBoundPacket { +impl ServerBoundGamePacket { pub fn get_type_id(&self) -> u8 { match self { Self::TeleportConfirm(_) => 0x00, @@ -801,7 +801,7 @@ impl GameServerBoundPacket { } } -pub enum GameClientBoundPacket { +pub enum ClientBoundGamePacket { SpawnEntity(SpawnEntity), SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), SpawnEntityWeather(SpawnEntityWeather), @@ -897,7 +897,7 @@ pub enum GameClientBoundPacket { AcknowledgePlayerDigging(AcknowledgePlayerDigging), } -impl GameClientBoundPacket { +impl ClientBoundGamePacket { pub fn get_type_id(&self) -> u8 { match self { Self::SpawnEntity(_) => 0x00, @@ -1700,7 +1700,7 @@ impl GameClientBoundPacket { Self::NbtQueryResponse(nbt_query_response) } - pub fn client_bound_chat(message: Message, position: MessagePosition) -> Self { + pub fn client_bound_chat(message: String, position: i8) -> Self { let client_bound_chat = ClientBoundChat { message, position }; Self::ClientBoundChat(client_bound_chat) @@ -3004,8 +3004,8 @@ pub struct NbtQueryResponse { #[derive(Packet, Debug)] pub struct ClientBoundChat { - pub message: Message, - pub position: MessagePosition, + pub message: String, + pub position: i8, } #[derive(Packet, Debug)] diff --git a/protocol/src/version/v_1_14_4/handshake.rs b/protocol/src/version/v_1_14_4/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_14_4/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_14_4/login.rs b/protocol/src/version/v_1_14_4/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_14_4/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_14_4/mod.rs b/protocol/src/version/v_1_14_4/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_14_4/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_14_4/status.rs b/protocol/src/version/v_1_14_4/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_14_4/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_15/game.rs b/protocol/src/version/v_1_15/game.rs new file mode 100644 index 0000000..3b27cf6 --- /dev/null +++ b/protocol/src/version/v_1_15/game.rs @@ -0,0 +1,3573 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x58, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete(_) => 0x11, + Self::DeclareCommands(_) => 0x12, + Self::FacePlayer(_) => 0x35, + Self::NbtQueryResponse(_) => 0x55, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x13, + Self::ClientBoundCloseWindow(_) => 0x14, + Self::OpenWindow(_) => 0x2F, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::OpenHorseWindow(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::UpdateLight(_) => 0x25, + Self::JoinGame(_) => 0x26, + Self::Map(_) => 0x27, + Self::TradeList(_) => 0x28, + Self::RelEntityMove(_) => 0x29, + Self::EntityMoveLook(_) => 0x2A, + Self::EntityLook(_) => 0x2B, + Self::Entity(_) => 0x2C, + Self::ClientBoundVehicleMove(_) => 0x2D, + Self::OpenBook(_) => 0x2E, + Self::OpenSignEntity(_) => 0x30, + Self::CraftRecipeResponse(_) => 0x31, + Self::ClientBoundAbilities(_) => 0x32, + Self::CombatEvent(_) => 0x33, + Self::PlayerInfo(_) => 0x34, + Self::ClientBoundPosition(_) => 0x36, + Self::UnlockRecipes(_) => 0x37, + Self::EntityDestroy => 0x38, + Self::RemoveEntityEffect(_) => 0x39, + Self::ResourcePackSend(_) => 0x3A, + Self::Respawn(_) => 0x3B, + Self::EntityHeadRotation(_) => 0x3C, + Self::WorldBorder(_) => 0x3E, + Self::Camera(_) => 0x3F, + Self::ClientBoundHeldItemSlot(_) => 0x40, + Self::UpdateViewPosition(_) => 0x41, + Self::UpdateViewDistance(_) => 0x42, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x4E, + Self::UpdateTime(_) => 0x4F, + Self::Title(_) => 0x50, + Self::EntitySoundEffect(_) => 0x51, + Self::StopSound(_) => 0x53, + Self::SoundEffect(_) => 0x52, + Self::PlayerlistHeader(_) => 0x54, + Self::Collect(_) => 0x56, + Self::EntityTeleport(_) => 0x57, + Self::EntityUpdateAttributes(_) => 0x59, + Self::EntityEffect(_) => 0x5A, + Self::SelectAdvancementTab(_) => 0x3D, + Self::DeclareRecipes => 0x5B, + Self::Tags(_) => 0x5C, + Self::AcknowledgePlayerDigging(_) => 0x08, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x58 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x11 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x12 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x35 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x55 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x13 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x14 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2F => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x26 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x27 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x29 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x2A => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2B => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2C => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2D => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2E => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x30 => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x31 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x32 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x33 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x34 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x36 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x37 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x38 => Ok(Self::EntityDestroy), + 0x39 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x3A => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3B => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3C => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3E => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3F => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x40 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x41 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x42 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4E => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4F => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x50 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x51 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x53 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x52 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x54 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x56 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x57 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x59 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x5A => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3D => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5B => Ok(Self::DeclareRecipes), + 0x5C => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x08 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + hashed_seed: i64, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + hashed_seed, + max_players, + level_type, + view_distance, + reduced_debug_info, + enable_respawn_screen, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, hashed_seed: i64, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + hashed_seed, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub hashed_seed: i64, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub hashed_seed: i64, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_15/handshake.rs b/protocol/src/version/v_1_15/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_15/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_15/login.rs b/protocol/src/version/v_1_15/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_15/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_15/mod.rs b/protocol/src/version/v_1_15/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_15/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_15/status.rs b/protocol/src/version/v_1_15/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_15/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_15_1/game.rs b/protocol/src/version/v_1_15_1/game.rs new file mode 100644 index 0000000..3b27cf6 --- /dev/null +++ b/protocol/src/version/v_1_15_1/game.rs @@ -0,0 +1,3573 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x58, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete(_) => 0x11, + Self::DeclareCommands(_) => 0x12, + Self::FacePlayer(_) => 0x35, + Self::NbtQueryResponse(_) => 0x55, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x13, + Self::ClientBoundCloseWindow(_) => 0x14, + Self::OpenWindow(_) => 0x2F, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::OpenHorseWindow(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::UpdateLight(_) => 0x25, + Self::JoinGame(_) => 0x26, + Self::Map(_) => 0x27, + Self::TradeList(_) => 0x28, + Self::RelEntityMove(_) => 0x29, + Self::EntityMoveLook(_) => 0x2A, + Self::EntityLook(_) => 0x2B, + Self::Entity(_) => 0x2C, + Self::ClientBoundVehicleMove(_) => 0x2D, + Self::OpenBook(_) => 0x2E, + Self::OpenSignEntity(_) => 0x30, + Self::CraftRecipeResponse(_) => 0x31, + Self::ClientBoundAbilities(_) => 0x32, + Self::CombatEvent(_) => 0x33, + Self::PlayerInfo(_) => 0x34, + Self::ClientBoundPosition(_) => 0x36, + Self::UnlockRecipes(_) => 0x37, + Self::EntityDestroy => 0x38, + Self::RemoveEntityEffect(_) => 0x39, + Self::ResourcePackSend(_) => 0x3A, + Self::Respawn(_) => 0x3B, + Self::EntityHeadRotation(_) => 0x3C, + Self::WorldBorder(_) => 0x3E, + Self::Camera(_) => 0x3F, + Self::ClientBoundHeldItemSlot(_) => 0x40, + Self::UpdateViewPosition(_) => 0x41, + Self::UpdateViewDistance(_) => 0x42, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x4E, + Self::UpdateTime(_) => 0x4F, + Self::Title(_) => 0x50, + Self::EntitySoundEffect(_) => 0x51, + Self::StopSound(_) => 0x53, + Self::SoundEffect(_) => 0x52, + Self::PlayerlistHeader(_) => 0x54, + Self::Collect(_) => 0x56, + Self::EntityTeleport(_) => 0x57, + Self::EntityUpdateAttributes(_) => 0x59, + Self::EntityEffect(_) => 0x5A, + Self::SelectAdvancementTab(_) => 0x3D, + Self::DeclareRecipes => 0x5B, + Self::Tags(_) => 0x5C, + Self::AcknowledgePlayerDigging(_) => 0x08, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x58 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x11 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x12 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x35 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x55 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x13 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x14 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2F => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x26 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x27 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x29 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x2A => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2B => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2C => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2D => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2E => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x30 => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x31 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x32 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x33 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x34 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x36 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x37 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x38 => Ok(Self::EntityDestroy), + 0x39 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x3A => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3B => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3C => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3E => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3F => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x40 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x41 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x42 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4E => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4F => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x50 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x51 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x53 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x52 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x54 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x56 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x57 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x59 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x5A => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3D => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5B => Ok(Self::DeclareRecipes), + 0x5C => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x08 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + hashed_seed: i64, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + hashed_seed, + max_players, + level_type, + view_distance, + reduced_debug_info, + enable_respawn_screen, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, hashed_seed: i64, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + hashed_seed, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub hashed_seed: i64, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub hashed_seed: i64, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_15_1/handshake.rs b/protocol/src/version/v_1_15_1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_15_1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_15_1/login.rs b/protocol/src/version/v_1_15_1/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_15_1/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_15_1/mod.rs b/protocol/src/version/v_1_15_1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_15_1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_15_1/status.rs b/protocol/src/version/v_1_15_1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_15_1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_15_2/game.rs b/protocol/src/version/v_1_15_2/game.rs new file mode 100644 index 0000000..3b27cf6 --- /dev/null +++ b/protocol/src/version/v_1_15_2/game.rs @@ -0,0 +1,3573 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + attachment_type: String, + target_pool: String, + final_state: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + attachment_type, + target_pool, + final_state, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x58, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete(_) => 0x11, + Self::DeclareCommands(_) => 0x12, + Self::FacePlayer(_) => 0x35, + Self::NbtQueryResponse(_) => 0x55, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x13, + Self::ClientBoundCloseWindow(_) => 0x14, + Self::OpenWindow(_) => 0x2F, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::OpenHorseWindow(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::UpdateLight(_) => 0x25, + Self::JoinGame(_) => 0x26, + Self::Map(_) => 0x27, + Self::TradeList(_) => 0x28, + Self::RelEntityMove(_) => 0x29, + Self::EntityMoveLook(_) => 0x2A, + Self::EntityLook(_) => 0x2B, + Self::Entity(_) => 0x2C, + Self::ClientBoundVehicleMove(_) => 0x2D, + Self::OpenBook(_) => 0x2E, + Self::OpenSignEntity(_) => 0x30, + Self::CraftRecipeResponse(_) => 0x31, + Self::ClientBoundAbilities(_) => 0x32, + Self::CombatEvent(_) => 0x33, + Self::PlayerInfo(_) => 0x34, + Self::ClientBoundPosition(_) => 0x36, + Self::UnlockRecipes(_) => 0x37, + Self::EntityDestroy => 0x38, + Self::RemoveEntityEffect(_) => 0x39, + Self::ResourcePackSend(_) => 0x3A, + Self::Respawn(_) => 0x3B, + Self::EntityHeadRotation(_) => 0x3C, + Self::WorldBorder(_) => 0x3E, + Self::Camera(_) => 0x3F, + Self::ClientBoundHeldItemSlot(_) => 0x40, + Self::UpdateViewPosition(_) => 0x41, + Self::UpdateViewDistance(_) => 0x42, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x4E, + Self::UpdateTime(_) => 0x4F, + Self::Title(_) => 0x50, + Self::EntitySoundEffect(_) => 0x51, + Self::StopSound(_) => 0x53, + Self::SoundEffect(_) => 0x52, + Self::PlayerlistHeader(_) => 0x54, + Self::Collect(_) => 0x56, + Self::EntityTeleport(_) => 0x57, + Self::EntityUpdateAttributes(_) => 0x59, + Self::EntityEffect(_) => 0x5A, + Self::SelectAdvancementTab(_) => 0x3D, + Self::DeclareRecipes => 0x5B, + Self::Tags(_) => 0x5C, + Self::AcknowledgePlayerDigging(_) => 0x08, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x58 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x11 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x12 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x35 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x55 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x13 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x14 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2F => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x26 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x27 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x29 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x2A => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2B => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2C => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2D => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2E => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x30 => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x31 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x32 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x33 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x34 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x36 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x37 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x38 => Ok(Self::EntityDestroy), + 0x39 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x3A => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3B => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3C => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3E => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3F => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x40 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x41 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x42 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x4E => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4F => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x50 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x51 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x53 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x52 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x54 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x56 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x57 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x59 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x5A => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3D => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5B => Ok(Self::DeclareRecipes), + 0x5C => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x08 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + hashed_seed: i64, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + hashed_seed, + max_players, + level_type, + view_distance, + reduced_debug_info, + enable_respawn_screen, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, hashed_seed: i64, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + hashed_seed, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub attachment_type: String, + pub target_pool: String, + pub final_state: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub hashed_seed: i64, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub hashed_seed: i64, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_15_2/handshake.rs b/protocol/src/version/v_1_15_2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_15_2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_15_2/login.rs b/protocol/src/version/v_1_15_2/login.rs new file mode 100644 index 0000000..fcbf5cc --- /dev/null +++ b/protocol/src/version/v_1_15_2/login.rs @@ -0,0 +1,209 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_15_2/mod.rs b/protocol/src/version/v_1_15_2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_15_2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_15_2/status.rs b/protocol/src/version/v_1_15_2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_15_2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_16/game.rs b/protocol/src/version/v_1_16/game.rs new file mode 100644 index 0000000..70250d5 --- /dev/null +++ b/protocol/src/version/v_1_16/game.rs @@ -0,0 +1,3607 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + GenerateStructure(GenerateStructure), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x18, + Self::NameItem(_) => 0x1F, + Self::SelectTrade(_) => 0x22, + Self::SetBeaconEffect(_) => 0x23, + Self::UpdateCommandBlock(_) => 0x25, + Self::UpdateCommandBlockMinecart(_) => 0x26, + Self::UpdateStructureBlock(_) => 0x29, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::GenerateStructure(_) => 0x0F, + Self::ServerBoundKeepAlive(_) => 0x10, + Self::LockDifficulty(_) => 0x11, + Self::ServerBoundPosition(_) => 0x12, + Self::PositionLook(_) => 0x13, + Self::Look(_) => 0x14, + Self::Flying(_) => 0x15, + Self::ServerBoundVehicleMove(_) => 0x16, + Self::SteerBoat(_) => 0x17, + Self::CraftRecipeRequest(_) => 0x19, + Self::ServerBoundAbilities(_) => 0x1A, + Self::BlockDig(_) => 0x1B, + Self::EntityAction(_) => 0x1C, + Self::SteerVehicle(_) => 0x1D, + Self::CraftingBookData(_) => 0x1E, + Self::ResourcePackReceive(_) => 0x20, + Self::ServerBoundHeldItemSlot(_) => 0x24, + Self::SetCreativeSlot(_) => 0x27, + Self::UpdateJigsawBlock(_) => 0x28, + Self::UpdateSign(_) => 0x2A, + Self::ArmAnimation(_) => 0x2B, + Self::Spectate(_) => 0x2C, + Self::BlockPlace(_) => 0x2D, + Self::UseItem(_) => 0x2E, + Self::AdvancementTab(_) => 0x21, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x18 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1F => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x22 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x23 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x25 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x26 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x29 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let generate_structure = GenerateStructure::decode(reader)?; + + Ok(Self::GenerateStructure(generate_structure)) + } + 0x10 => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x11 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x12 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x13 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x14 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x15 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x16 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x17 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x19 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x1A => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1B => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1C => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1D => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1E => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x20 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x24 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x27 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x28 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x2A => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2B => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2C => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2D => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2E => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x21 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32, sneaking: bool) -> Self { + let use_entity = UseEntity { + target, + mouse, + sneaking, + }; + + Self::UseEntity(use_entity) + } + + pub fn generate_structure(location: Position, levels: i32, keep_jigsaws: bool) -> Self { + let generate_structure = GenerateStructure { + location, + levels, + keep_jigsaws, + }; + + Self::GenerateStructure(generate_structure) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8) -> Self { + let server_bound_abilities = ServerBoundAbilities { flags }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + name: String, + target: String, + pool: String, + final_state: String, + joint_type: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + name, + target, + pool, + final_state, + joint_type, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityLiving(_) => 0x02, + Self::SpawnEntityPainting(_) => 0x03, + Self::NamedEntitySpawn(_) => 0x04, + Self::Animation(_) => 0x05, + Self::Statistics => 0x06, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x42, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + Self::AcknowledgePlayerDigging(_) => 0x07, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x03 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x04 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x05 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x06 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x42 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x07 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8, sender: Uuid) -> Self { + let client_bound_chat = ClientBoundChat { + message, + position, + sender, + }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + ignore_old_data: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + ignore_old_data, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + trust_edges: bool, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + trust_edges, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + previous_game_mode: u8, + dimension_codec: CompoundTag, + dimension: String, + world_name: String, + hashed_seed: i64, + max_players: u8, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + is_debug: bool, + is_flat: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + previous_game_mode, + dimension_codec, + dimension, + world_name, + hashed_seed, + max_players, + view_distance, + reduced_debug_info, + enable_respawn_screen, + is_debug, + is_flat, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn( + dimension: String, + world_name: String, + hashed_seed: i64, + gamemode: u8, + previous_gamemode: u8, + is_debug: bool, + is_flat: bool, + copy_metadata: bool, + ) -> Self { + let respawn = Respawn { + dimension, + world_name, + hashed_seed, + gamemode, + previous_gamemode, + is_debug, + is_flat, + copy_metadata, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32) -> Self { + let entity_equipment = EntityEquipment { entity_id }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, + pub sneaking: bool, +} + +#[derive(Packet, Debug)] +pub struct GenerateStructure { + pub location: Position, + #[packet(with = "var_int")] + pub levels: i32, + pub keep_jigsaws: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint_type: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, + pub sender: Uuid, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + pub ignore_old_data: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + pub trust_edges: bool, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub previous_game_mode: u8, + pub dimension_codec: CompoundTag, + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub max_players: u8, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub gamemode: u8, + pub previous_gamemode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_16/handshake.rs b/protocol/src/version/v_1_16/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_16/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/packet/login.rs b/protocol/src/version/v_1_16/login.rs similarity index 95% rename from protocol/src/packet/login.rs rename to protocol/src/version/v_1_16/login.rs index bb548cd..d29fe54 100644 --- a/protocol/src/packet/login.rs +++ b/protocol/src/version/v_1_16/login.rs @@ -1,19 +1,19 @@ // This file is automatically generated. // It is not intended for manual editing. -use crate::data::chat::Message; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; use std::io::Read; + use uuid::Uuid; -pub enum LoginServerBoundPacket { +pub enum ServerBoundLoginPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), LoginPluginResponse(LoginPluginResponse), } -impl LoginServerBoundPacket { +impl ServerBoundLoginPacket { pub fn get_type_id(&self) -> u8 { match self { Self::LoginStart(_) => 0x00, @@ -65,7 +65,7 @@ impl LoginServerBoundPacket { } } -pub enum LoginClientBoundPacket { +pub enum ClientBoundLoginPacket { Disconnect(Disconnect), EncryptionRequest(EncryptionRequest), Success(Success), @@ -73,7 +73,7 @@ pub enum LoginClientBoundPacket { LoginPluginRequest(LoginPluginRequest), } -impl LoginClientBoundPacket { +impl ClientBoundLoginPacket { pub fn get_type_id(&self) -> u8 { match self { Self::Disconnect(_) => 0x00, @@ -115,7 +115,7 @@ impl LoginClientBoundPacket { } } - pub fn disconnect(reason: Message) -> Self { + pub fn disconnect(reason: String) -> Self { let disconnect = Disconnect { reason }; Self::Disconnect(disconnect) @@ -179,7 +179,7 @@ pub struct LoginPluginResponse { #[derive(Packet, Debug)] pub struct Disconnect { - pub reason: Message, + pub reason: String, } #[derive(Packet, Debug)] @@ -191,7 +191,6 @@ pub struct EncryptionRequest { #[derive(Packet, Debug)] pub struct Success { - #[packet(with = "uuid_hyp_str")] pub uuid: Uuid, pub username: String, } diff --git a/protocol/src/version/v_1_16/mod.rs b/protocol/src/version/v_1_16/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_16/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_16/status.rs b/protocol/src/version/v_1_16/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_16/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_16_1/game.rs b/protocol/src/version/v_1_16_1/game.rs new file mode 100644 index 0000000..70250d5 --- /dev/null +++ b/protocol/src/version/v_1_16_1/game.rs @@ -0,0 +1,3607 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + GenerateStructure(GenerateStructure), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x18, + Self::NameItem(_) => 0x1F, + Self::SelectTrade(_) => 0x22, + Self::SetBeaconEffect(_) => 0x23, + Self::UpdateCommandBlock(_) => 0x25, + Self::UpdateCommandBlockMinecart(_) => 0x26, + Self::UpdateStructureBlock(_) => 0x29, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::GenerateStructure(_) => 0x0F, + Self::ServerBoundKeepAlive(_) => 0x10, + Self::LockDifficulty(_) => 0x11, + Self::ServerBoundPosition(_) => 0x12, + Self::PositionLook(_) => 0x13, + Self::Look(_) => 0x14, + Self::Flying(_) => 0x15, + Self::ServerBoundVehicleMove(_) => 0x16, + Self::SteerBoat(_) => 0x17, + Self::CraftRecipeRequest(_) => 0x19, + Self::ServerBoundAbilities(_) => 0x1A, + Self::BlockDig(_) => 0x1B, + Self::EntityAction(_) => 0x1C, + Self::SteerVehicle(_) => 0x1D, + Self::CraftingBookData(_) => 0x1E, + Self::ResourcePackReceive(_) => 0x20, + Self::ServerBoundHeldItemSlot(_) => 0x24, + Self::SetCreativeSlot(_) => 0x27, + Self::UpdateJigsawBlock(_) => 0x28, + Self::UpdateSign(_) => 0x2A, + Self::ArmAnimation(_) => 0x2B, + Self::Spectate(_) => 0x2C, + Self::BlockPlace(_) => 0x2D, + Self::UseItem(_) => 0x2E, + Self::AdvancementTab(_) => 0x21, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x18 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1F => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x22 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x23 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x25 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x26 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x29 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let generate_structure = GenerateStructure::decode(reader)?; + + Ok(Self::GenerateStructure(generate_structure)) + } + 0x10 => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x11 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x12 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x13 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x14 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x15 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x16 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x17 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x19 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x1A => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1B => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1C => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1D => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1E => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x20 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x24 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x27 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x28 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x2A => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2B => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2C => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2D => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2E => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x21 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32, sneaking: bool) -> Self { + let use_entity = UseEntity { + target, + mouse, + sneaking, + }; + + Self::UseEntity(use_entity) + } + + pub fn generate_structure(location: Position, levels: i32, keep_jigsaws: bool) -> Self { + let generate_structure = GenerateStructure { + location, + levels, + keep_jigsaws, + }; + + Self::GenerateStructure(generate_structure) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8) -> Self { + let server_bound_abilities = ServerBoundAbilities { flags }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + name: String, + target: String, + pool: String, + final_state: String, + joint_type: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + name, + target, + pool, + final_state, + joint_type, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityLiving(_) => 0x02, + Self::SpawnEntityPainting(_) => 0x03, + Self::NamedEntitySpawn(_) => 0x04, + Self::Animation(_) => 0x05, + Self::Statistics => 0x06, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x42, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + Self::AcknowledgePlayerDigging(_) => 0x07, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x03 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x04 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x05 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x06 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x42 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x07 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8, sender: Uuid) -> Self { + let client_bound_chat = ClientBoundChat { + message, + position, + sender, + }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + ignore_old_data: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + ignore_old_data, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + trust_edges: bool, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + trust_edges, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + previous_game_mode: u8, + dimension_codec: CompoundTag, + dimension: String, + world_name: String, + hashed_seed: i64, + max_players: u8, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + is_debug: bool, + is_flat: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + previous_game_mode, + dimension_codec, + dimension, + world_name, + hashed_seed, + max_players, + view_distance, + reduced_debug_info, + enable_respawn_screen, + is_debug, + is_flat, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn( + dimension: String, + world_name: String, + hashed_seed: i64, + gamemode: u8, + previous_gamemode: u8, + is_debug: bool, + is_flat: bool, + copy_metadata: bool, + ) -> Self { + let respawn = Respawn { + dimension, + world_name, + hashed_seed, + gamemode, + previous_gamemode, + is_debug, + is_flat, + copy_metadata, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32) -> Self { + let entity_equipment = EntityEquipment { entity_id }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, + pub sneaking: bool, +} + +#[derive(Packet, Debug)] +pub struct GenerateStructure { + pub location: Position, + #[packet(with = "var_int")] + pub levels: i32, + pub keep_jigsaws: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint_type: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, + pub sender: Uuid, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + pub ignore_old_data: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + pub trust_edges: bool, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub previous_game_mode: u8, + pub dimension_codec: CompoundTag, + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub max_players: u8, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub gamemode: u8, + pub previous_gamemode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_16_1/handshake.rs b/protocol/src/version/v_1_16_1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_16_1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_16_1/login.rs b/protocol/src/version/v_1_16_1/login.rs new file mode 100644 index 0000000..d29fe54 --- /dev/null +++ b/protocol/src/version/v_1_16_1/login.rs @@ -0,0 +1,211 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use uuid::Uuid; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: Uuid, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: Uuid, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_16_1/mod.rs b/protocol/src/version/v_1_16_1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_16_1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_16_1/status.rs b/protocol/src/version/v_1_16_1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_16_1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_16_2/game.rs b/protocol/src/version/v_1_16_2/game.rs new file mode 100644 index 0000000..575196a --- /dev/null +++ b/protocol/src/version/v_1_16_2/game.rs @@ -0,0 +1,3643 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + GenerateStructure(GenerateStructure), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + DisplayedRecipe(DisplayedRecipe), + RecipeBook(RecipeBook), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x18, + Self::NameItem(_) => 0x20, + Self::SelectTrade(_) => 0x23, + Self::SetBeaconEffect(_) => 0x24, + Self::UpdateCommandBlock(_) => 0x26, + Self::UpdateCommandBlockMinecart(_) => 0x27, + Self::UpdateStructureBlock(_) => 0x2A, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::GenerateStructure(_) => 0x0F, + Self::ServerBoundKeepAlive(_) => 0x10, + Self::LockDifficulty(_) => 0x11, + Self::ServerBoundPosition(_) => 0x12, + Self::PositionLook(_) => 0x13, + Self::Look(_) => 0x14, + Self::Flying(_) => 0x15, + Self::ServerBoundVehicleMove(_) => 0x16, + Self::SteerBoat(_) => 0x17, + Self::CraftRecipeRequest(_) => 0x19, + Self::ServerBoundAbilities(_) => 0x1A, + Self::BlockDig(_) => 0x1B, + Self::EntityAction(_) => 0x1C, + Self::SteerVehicle(_) => 0x1D, + Self::DisplayedRecipe(_) => 0x1E, + Self::RecipeBook(_) => 0x1F, + Self::ResourcePackReceive(_) => 0x21, + Self::ServerBoundHeldItemSlot(_) => 0x25, + Self::SetCreativeSlot(_) => 0x28, + Self::UpdateJigsawBlock(_) => 0x29, + Self::UpdateSign(_) => 0x2B, + Self::ArmAnimation(_) => 0x2C, + Self::Spectate(_) => 0x2D, + Self::BlockPlace(_) => 0x2E, + Self::UseItem(_) => 0x2F, + Self::AdvancementTab(_) => 0x22, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x18 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x20 => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x23 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x24 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x26 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x27 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x2A => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let generate_structure = GenerateStructure::decode(reader)?; + + Ok(Self::GenerateStructure(generate_structure)) + } + 0x10 => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x11 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x12 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x13 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x14 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x15 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x16 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x17 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x19 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x1A => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1B => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1C => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1D => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1E => { + let displayed_recipe = DisplayedRecipe::decode(reader)?; + + Ok(Self::DisplayedRecipe(displayed_recipe)) + } + 0x1F => { + let recipe_book = RecipeBook::decode(reader)?; + + Ok(Self::RecipeBook(recipe_book)) + } + 0x21 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x25 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x28 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x29 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x2B => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2C => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2D => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2E => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2F => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x22 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32, sneaking: bool) -> Self { + let use_entity = UseEntity { + target, + mouse, + sneaking, + }; + + Self::UseEntity(use_entity) + } + + pub fn generate_structure(location: Position, levels: i32, keep_jigsaws: bool) -> Self { + let generate_structure = GenerateStructure { + location, + levels, + keep_jigsaws, + }; + + Self::GenerateStructure(generate_structure) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8) -> Self { + let server_bound_abilities = ServerBoundAbilities { flags }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn displayed_recipe(recipe_id: String) -> Self { + let displayed_recipe = DisplayedRecipe { recipe_id }; + + Self::DisplayedRecipe(displayed_recipe) + } + + pub fn recipe_book(book_id: i32, book_open: bool, filter_active: bool) -> Self { + let recipe_book = RecipeBook { + book_id, + book_open, + filter_active, + }; + + Self::RecipeBook(recipe_book) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + name: String, + target: String, + pool: String, + final_state: String, + joint_type: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + name, + target, + pool, + final_state, + joint_type, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityLiving(_) => 0x02, + Self::SpawnEntityPainting(_) => 0x03, + Self::NamedEntitySpawn(_) => 0x04, + Self::Animation(_) => 0x05, + Self::Statistics => 0x06, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x0F, + Self::DeclareCommands(_) => 0x10, + Self::FacePlayer(_) => 0x33, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x3B, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x2D, + Self::WindowItems(_) => 0x13, + Self::CraftProgressBar(_) => 0x14, + Self::SetSlot(_) => 0x15, + Self::SetCooldown(_) => 0x16, + Self::ClientBoundCustomPayload(_) => 0x17, + Self::NamedSoundEffect(_) => 0x18, + Self::KickDisconnect(_) => 0x19, + Self::EntityStatus(_) => 0x1A, + Self::Explosion(_) => 0x1B, + Self::UnloadChunk(_) => 0x1C, + Self::GameStateChange(_) => 0x1D, + Self::OpenHorseWindow(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::UpdateLight(_) => 0x23, + Self::JoinGame(_) => 0x24, + Self::Map(_) => 0x25, + Self::TradeList(_) => 0x26, + Self::RelEntityMove(_) => 0x27, + Self::EntityMoveLook(_) => 0x28, + Self::EntityLook(_) => 0x29, + Self::Entity(_) => 0x2A, + Self::ClientBoundVehicleMove(_) => 0x2B, + Self::OpenBook(_) => 0x2C, + Self::OpenSignEntity(_) => 0x2E, + Self::CraftRecipeResponse(_) => 0x2F, + Self::ClientBoundAbilities(_) => 0x30, + Self::CombatEvent(_) => 0x31, + Self::PlayerInfo(_) => 0x32, + Self::ClientBoundPosition(_) => 0x34, + Self::UnlockRecipes(_) => 0x35, + Self::EntityDestroy => 0x36, + Self::RemoveEntityEffect(_) => 0x37, + Self::ResourcePackSend(_) => 0x38, + Self::Respawn(_) => 0x39, + Self::EntityHeadRotation(_) => 0x3A, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x42, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + Self::AcknowledgePlayerDigging(_) => 0x07, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x03 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x04 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x05 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x06 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0F => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x10 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x33 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x3B => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2D => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x13 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x14 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x15 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x16 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x17 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x18 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x19 => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1A => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1B => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1C => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1D => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1E => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x24 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x25 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x26 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x27 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x28 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x29 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2A => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2B => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2C => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2E => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2F => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x30 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x31 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x32 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x34 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x35 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x36 => Ok(Self::EntityDestroy), + 0x37 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x38 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x39 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3A => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x42 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x07 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8, sender: Uuid) -> Self { + let client_bound_chat = ClientBoundChat { + message, + position, + sender, + }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(not_trust_edges: bool) -> Self { + let multi_block_change = MultiBlockChange { not_trust_edges }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + trust_edges: bool, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + trust_edges, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + is_hardcore: bool, + game_mode: u8, + previous_game_mode: u8, + dimension_codec: CompoundTag, + dimension: CompoundTag, + world_name: String, + hashed_seed: i64, + max_players: i32, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + is_debug: bool, + is_flat: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + is_hardcore, + game_mode, + previous_game_mode, + dimension_codec, + dimension, + world_name, + hashed_seed, + max_players, + view_distance, + reduced_debug_info, + enable_respawn_screen, + is_debug, + is_flat, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + blast_furnace_open: bool, + filtering_blast_furnace: bool, + smoker_book_open: bool, + filtering_smoker: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + blast_furnace_open, + filtering_blast_furnace, + smoker_book_open, + filtering_smoker, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn( + dimension: CompoundTag, + world_name: String, + hashed_seed: i64, + gamemode: u8, + previous_gamemode: u8, + is_debug: bool, + is_flat: bool, + copy_metadata: bool, + ) -> Self { + let respawn = Respawn { + dimension, + world_name, + hashed_seed, + gamemode, + previous_gamemode, + is_debug, + is_flat, + copy_metadata, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32) -> Self { + let entity_equipment = EntityEquipment { entity_id }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, + pub sneaking: bool, +} + +#[derive(Packet, Debug)] +pub struct GenerateStructure { + pub location: Position, + #[packet(with = "var_int")] + pub levels: i32, + pub keep_jigsaws: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct DisplayedRecipe { + pub recipe_id: String, +} + +#[derive(Packet, Debug)] +pub struct RecipeBook { + #[packet(with = "var_int")] + pub book_id: i32, + pub book_open: bool, + pub filter_active: bool, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint_type: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, + pub sender: Uuid, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub not_trust_edges: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + pub trust_edges: bool, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub is_hardcore: bool, + pub game_mode: u8, + pub previous_game_mode: u8, + pub dimension_codec: CompoundTag, + pub dimension: CompoundTag, + pub world_name: String, + pub hashed_seed: i64, + #[packet(with = "var_int")] + pub max_players: i32, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, + pub blast_furnace_open: bool, + pub filtering_blast_furnace: bool, + pub smoker_book_open: bool, + pub filtering_smoker: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: CompoundTag, + pub world_name: String, + pub hashed_seed: i64, + pub gamemode: u8, + pub previous_gamemode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_16_2/handshake.rs b/protocol/src/version/v_1_16_2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_16_2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_16_2/login.rs b/protocol/src/version/v_1_16_2/login.rs new file mode 100644 index 0000000..d29fe54 --- /dev/null +++ b/protocol/src/version/v_1_16_2/login.rs @@ -0,0 +1,211 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use uuid::Uuid; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: Uuid, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: Uuid, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_16_2/mod.rs b/protocol/src/version/v_1_16_2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_16_2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_16_2/status.rs b/protocol/src/version/v_1_16_2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_16_2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_16_rc1/game.rs b/protocol/src/version/v_1_16_rc1/game.rs new file mode 100644 index 0000000..70250d5 --- /dev/null +++ b/protocol/src/version/v_1_16_rc1/game.rs @@ -0,0 +1,3607 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + GenerateStructure(GenerateStructure), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x18, + Self::NameItem(_) => 0x1F, + Self::SelectTrade(_) => 0x22, + Self::SetBeaconEffect(_) => 0x23, + Self::UpdateCommandBlock(_) => 0x25, + Self::UpdateCommandBlockMinecart(_) => 0x26, + Self::UpdateStructureBlock(_) => 0x29, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::GenerateStructure(_) => 0x0F, + Self::ServerBoundKeepAlive(_) => 0x10, + Self::LockDifficulty(_) => 0x11, + Self::ServerBoundPosition(_) => 0x12, + Self::PositionLook(_) => 0x13, + Self::Look(_) => 0x14, + Self::Flying(_) => 0x15, + Self::ServerBoundVehicleMove(_) => 0x16, + Self::SteerBoat(_) => 0x17, + Self::CraftRecipeRequest(_) => 0x19, + Self::ServerBoundAbilities(_) => 0x1A, + Self::BlockDig(_) => 0x1B, + Self::EntityAction(_) => 0x1C, + Self::SteerVehicle(_) => 0x1D, + Self::CraftingBookData(_) => 0x1E, + Self::ResourcePackReceive(_) => 0x20, + Self::ServerBoundHeldItemSlot(_) => 0x24, + Self::SetCreativeSlot(_) => 0x27, + Self::UpdateJigsawBlock(_) => 0x28, + Self::UpdateSign(_) => 0x2A, + Self::ArmAnimation(_) => 0x2B, + Self::Spectate(_) => 0x2C, + Self::BlockPlace(_) => 0x2D, + Self::UseItem(_) => 0x2E, + Self::AdvancementTab(_) => 0x21, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x18 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1F => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x22 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x23 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x25 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x26 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x29 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let generate_structure = GenerateStructure::decode(reader)?; + + Ok(Self::GenerateStructure(generate_structure)) + } + 0x10 => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x11 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x12 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x13 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x14 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x15 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x16 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x17 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x19 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x1A => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1B => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1C => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1D => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1E => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x20 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x24 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x27 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x28 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x2A => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2B => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2C => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2D => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2E => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x21 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32, sneaking: bool) -> Self { + let use_entity = UseEntity { + target, + mouse, + sneaking, + }; + + Self::UseEntity(use_entity) + } + + pub fn generate_structure(location: Position, levels: i32, keep_jigsaws: bool) -> Self { + let generate_structure = GenerateStructure { + location, + levels, + keep_jigsaws, + }; + + Self::GenerateStructure(generate_structure) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8) -> Self { + let server_bound_abilities = ServerBoundAbilities { flags }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + name: String, + target: String, + pool: String, + final_state: String, + joint_type: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + name, + target, + pool, + final_state, + joint_type, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityLiving(_) => 0x02, + Self::SpawnEntityPainting(_) => 0x03, + Self::NamedEntitySpawn(_) => 0x04, + Self::Animation(_) => 0x05, + Self::Statistics => 0x06, + Self::Advancements(_) => 0x57, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete(_) => 0x10, + Self::DeclareCommands(_) => 0x11, + Self::FacePlayer(_) => 0x34, + Self::NbtQueryResponse(_) => 0x54, + Self::ClientBoundChat(_) => 0x0E, + Self::MultiBlockChange(_) => 0x0F, + Self::ClientBoundTransaction(_) => 0x12, + Self::ClientBoundCloseWindow(_) => 0x13, + Self::OpenWindow(_) => 0x2E, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::OpenHorseWindow(_) => 0x1F, + Self::ClientBoundKeepAlive(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::WorldEvent(_) => 0x22, + Self::WorldParticles(_) => 0x23, + Self::UpdateLight(_) => 0x24, + Self::JoinGame(_) => 0x25, + Self::Map(_) => 0x26, + Self::TradeList(_) => 0x27, + Self::RelEntityMove(_) => 0x28, + Self::EntityMoveLook(_) => 0x29, + Self::EntityLook(_) => 0x2A, + Self::Entity(_) => 0x2B, + Self::ClientBoundVehicleMove(_) => 0x2C, + Self::OpenBook(_) => 0x2D, + Self::OpenSignEntity(_) => 0x2F, + Self::CraftRecipeResponse(_) => 0x30, + Self::ClientBoundAbilities(_) => 0x31, + Self::CombatEvent(_) => 0x32, + Self::PlayerInfo(_) => 0x33, + Self::ClientBoundPosition(_) => 0x35, + Self::UnlockRecipes(_) => 0x36, + Self::EntityDestroy => 0x37, + Self::RemoveEntityEffect(_) => 0x38, + Self::ResourcePackSend(_) => 0x39, + Self::Respawn(_) => 0x3A, + Self::EntityHeadRotation(_) => 0x3B, + Self::WorldBorder(_) => 0x3D, + Self::Camera(_) => 0x3E, + Self::ClientBoundHeldItemSlot(_) => 0x3F, + Self::UpdateViewPosition(_) => 0x40, + Self::UpdateViewDistance(_) => 0x41, + Self::ScoreboardDisplayObjective(_) => 0x43, + Self::EntityMetadata(_) => 0x44, + Self::AttachEntity(_) => 0x45, + Self::EntityVelocity(_) => 0x46, + Self::EntityEquipment(_) => 0x47, + Self::Experience(_) => 0x48, + Self::UpdateHealth(_) => 0x49, + Self::ScoreboardObjective(_) => 0x4A, + Self::SetPassengers(_) => 0x4B, + Self::Teams(_) => 0x4C, + Self::ScoreboardScore(_) => 0x4D, + Self::SpawnPosition(_) => 0x42, + Self::UpdateTime(_) => 0x4E, + Self::Title(_) => 0x4F, + Self::EntitySoundEffect(_) => 0x50, + Self::StopSound(_) => 0x52, + Self::SoundEffect(_) => 0x51, + Self::PlayerlistHeader(_) => 0x53, + Self::Collect(_) => 0x55, + Self::EntityTeleport(_) => 0x56, + Self::EntityUpdateAttributes(_) => 0x58, + Self::EntityEffect(_) => 0x59, + Self::SelectAdvancementTab(_) => 0x3C, + Self::DeclareRecipes => 0x5A, + Self::Tags(_) => 0x5B, + Self::AcknowledgePlayerDigging(_) => 0x07, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x03 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x04 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x05 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x06 => Ok(Self::Statistics), + 0x57 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x10 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x11 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x34 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x54 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0E => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x0F => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x12 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x13 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2E => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x20 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x23 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x24 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x25 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x26 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x27 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x28 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x29 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2A => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2B => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2C => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2D => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x2F => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x30 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x31 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x32 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x33 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x35 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x36 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x37 => Ok(Self::EntityDestroy), + 0x38 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x39 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3A => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3B => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3D => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3E => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x3F => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x40 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x41 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x43 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x44 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x45 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x46 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x47 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x48 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x49 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4A => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4B => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4C => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4D => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x42 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4E => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x4F => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x50 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x52 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x51 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x53 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x55 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x56 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x58 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x59 => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3C => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5A => Ok(Self::DeclareRecipes), + 0x5B => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x07 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8, sender: Uuid) -> Self { + let client_bound_chat = ClientBoundChat { + message, + position, + sender, + }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + ignore_old_data: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + ignore_old_data, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + trust_edges: bool, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + trust_edges, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + previous_game_mode: u8, + dimension_codec: CompoundTag, + dimension: String, + world_name: String, + hashed_seed: i64, + max_players: u8, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + is_debug: bool, + is_flat: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + previous_game_mode, + dimension_codec, + dimension, + world_name, + hashed_seed, + max_players, + view_distance, + reduced_debug_info, + enable_respawn_screen, + is_debug, + is_flat, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn( + dimension: String, + world_name: String, + hashed_seed: i64, + gamemode: u8, + previous_gamemode: u8, + is_debug: bool, + is_flat: bool, + copy_metadata: bool, + ) -> Self { + let respawn = Respawn { + dimension, + world_name, + hashed_seed, + gamemode, + previous_gamemode, + is_debug, + is_flat, + copy_metadata, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32) -> Self { + let entity_equipment = EntityEquipment { entity_id }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, + pub sneaking: bool, +} + +#[derive(Packet, Debug)] +pub struct GenerateStructure { + pub location: Position, + #[packet(with = "var_int")] + pub levels: i32, + pub keep_jigsaws: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint_type: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, + pub sender: Uuid, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + pub ignore_old_data: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + pub trust_edges: bool, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub previous_game_mode: u8, + pub dimension_codec: CompoundTag, + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub max_players: u8, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: String, + pub world_name: String, + pub hashed_seed: i64, + pub gamemode: u8, + pub previous_gamemode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_1_16_rc1/handshake.rs b/protocol/src/version/v_1_16_rc1/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_16_rc1/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_16_rc1/login.rs b/protocol/src/version/v_1_16_rc1/login.rs new file mode 100644 index 0000000..d29fe54 --- /dev/null +++ b/protocol/src/version/v_1_16_rc1/login.rs @@ -0,0 +1,211 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use uuid::Uuid; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: Uuid, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: Uuid, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_1_16_rc1/mod.rs b/protocol/src/version/v_1_16_rc1/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_16_rc1/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_16_rc1/status.rs b/protocol/src/version/v_1_16_rc1/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_16_rc1/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_8/game.rs b/protocol/src/version/v_1_8/game.rs new file mode 100644 index 0000000..149f640 --- /dev/null +++ b/protocol/src/version/v_1_8/game.rs @@ -0,0 +1,2475 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundChat(ServerBoundChat), + UseEntity(UseEntity), + Flying(Flying), + ServerBoundPosition(ServerBoundPosition), + Look(Look), + PositionLook(PositionLook), + BlockDig(BlockDig), + BlockPlace(BlockPlace), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + ArmAnimation, + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ServerBoundCloseWindow(ServerBoundCloseWindow), + WindowClick(WindowClick), + ServerBoundTransaction(ServerBoundTransaction), + SetCreativeSlot(SetCreativeSlot), + EnchantItem(EnchantItem), + ServerBoundUpdateSign(ServerBoundUpdateSign), + ServerBoundAbilities(ServerBoundAbilities), + ServerBoundTabComplete(ServerBoundTabComplete), + Settings(Settings), + ClientCommand(ClientCommand), + ServerBoundCustomPayload(ServerBoundCustomPayload), + Spectate(Spectate), + ResourcePackReceive(ResourcePackReceive), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::ServerBoundKeepAlive(_) => 0x00, + Self::ServerBoundChat(_) => 0x01, + Self::UseEntity(_) => 0x02, + Self::Flying(_) => 0x03, + Self::ServerBoundPosition(_) => 0x04, + Self::Look(_) => 0x05, + Self::PositionLook(_) => 0x06, + Self::BlockDig(_) => 0x07, + Self::BlockPlace(_) => 0x08, + Self::ServerBoundHeldItemSlot(_) => 0x09, + Self::ArmAnimation => 0x0A, + Self::EntityAction(_) => 0x0B, + Self::SteerVehicle(_) => 0x0C, + Self::ServerBoundCloseWindow(_) => 0x0D, + Self::WindowClick(_) => 0x0E, + Self::ServerBoundTransaction(_) => 0x0F, + Self::SetCreativeSlot(_) => 0x10, + Self::EnchantItem(_) => 0x11, + Self::ServerBoundUpdateSign(_) => 0x12, + Self::ServerBoundAbilities(_) => 0x13, + Self::ServerBoundTabComplete(_) => 0x14, + Self::Settings(_) => 0x15, + Self::ClientCommand(_) => 0x16, + Self::ServerBoundCustomPayload(_) => 0x17, + Self::Spectate(_) => 0x18, + Self::ResourcePackReceive(_) => 0x19, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x01 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x02 => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x03 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x04 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x05 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x06 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x07 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x08 => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x09 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x0A => Ok(Self::ArmAnimation), + 0x0B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x0C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x0D => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0E => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0F => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x10 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x11 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x12 => { + let server_bound_update_sign = ServerBoundUpdateSign::decode(reader)?; + + Ok(Self::ServerBoundUpdateSign(server_bound_update_sign)) + } + 0x13 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x14 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x15 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x16 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x17 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x18 => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x19 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn block_place( + location: Position, + direction: i8, + held_item: Option, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + held_item, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn arm_animation() -> Self { + Self::ArmAnimation + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn server_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let server_bound_update_sign = ServerBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ServerBoundUpdateSign(server_bound_update_sign) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn server_bound_tab_complete(text: String, block: Position) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { text, block }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i8, + chat_colors: bool, + skin_parts: u8, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + }; + + Self::Settings(settings) + } + + pub fn client_command(payload: i32) -> Self { + let client_command = ClientCommand { payload }; + + Self::ClientCommand(client_command) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } +} + +pub enum ClientBoundGamePacket { + ClientBoundKeepAlive(ClientBoundKeepAlive), + JoinGame(JoinGame), + ClientBoundChat(ClientBoundChat), + UpdateTime(UpdateTime), + EntityEquipment(EntityEquipment), + SpawnPosition(SpawnPosition), + UpdateHealth(UpdateHealth), + Respawn(Respawn), + ClientBoundPosition(ClientBoundPosition), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + Bed(Bed), + Animation(Animation), + NamedEntitySpawn(NamedEntitySpawn), + Collect(Collect), + SpawnEntity(SpawnEntity), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + EntityVelocity(EntityVelocity), + EntityDestroy, + Entity(Entity), + RelEntityMove(RelEntityMove), + EntityLook(EntityLook), + EntityMoveLook(EntityMoveLook), + EntityTeleport(EntityTeleport), + EntityHeadRotation(EntityHeadRotation), + EntityStatus(EntityStatus), + AttachEntity(AttachEntity), + EntityMetadata(EntityMetadata), + EntityEffect(EntityEffect), + RemoveEntityEffect(RemoveEntityEffect), + Experience(Experience), + UpdateAttributes(UpdateAttributes), + MapChunk(MapChunk), + MultiBlockChange(MultiBlockChange), + BlockChange(BlockChange), + BlockAction(BlockAction), + BlockBreakAnimation(BlockBreakAnimation), + MapChunkBulk(MapChunkBulk), + Explosion(Explosion), + WorldEvent(WorldEvent), + NamedSoundEffect(NamedSoundEffect), + WorldParticles(WorldParticles), + GameStateChange(GameStateChange), + SpawnEntityWeather(SpawnEntityWeather), + OpenWindow(OpenWindow), + ClientBoundCloseWindow(ClientBoundCloseWindow), + SetSlot(SetSlot), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundUpdateSign(ClientBoundUpdateSign), + Map(Map), + TileEntityData(TileEntityData), + OpenSignEntity(OpenSignEntity), + Statistics, + PlayerInfo(PlayerInfo), + ClientBoundAbilities(ClientBoundAbilities), + ClientBoundTabComplete, + ScoreboardObjective(ScoreboardObjective), + ScoreboardScore(ScoreboardScore), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + ScoreboardTeam(ScoreboardTeam), + ClientBoundCustomPayload(ClientBoundCustomPayload), + KickDisconnect(KickDisconnect), + Difficulty(Difficulty), + CombatEvent(CombatEvent), + Camera(Camera), + WorldBorder(WorldBorder), + Title(Title), + SetCompression(SetCompression), + PlayerlistHeader(PlayerlistHeader), + ResourcePackSend(ResourcePackSend), + UpdateEntityNbt(UpdateEntityNbt), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::ClientBoundKeepAlive(_) => 0x00, + Self::JoinGame(_) => 0x01, + Self::ClientBoundChat(_) => 0x02, + Self::UpdateTime(_) => 0x03, + Self::EntityEquipment(_) => 0x04, + Self::SpawnPosition(_) => 0x05, + Self::UpdateHealth(_) => 0x06, + Self::Respawn(_) => 0x07, + Self::ClientBoundPosition(_) => 0x08, + Self::ClientBoundHeldItemSlot(_) => 0x09, + Self::Bed(_) => 0x0A, + Self::Animation(_) => 0x0B, + Self::NamedEntitySpawn(_) => 0x0C, + Self::Collect(_) => 0x0D, + Self::SpawnEntity(_) => 0x0E, + Self::SpawnEntityLiving(_) => 0x0F, + Self::SpawnEntityPainting(_) => 0x10, + Self::SpawnEntityExperienceOrb(_) => 0x11, + Self::EntityVelocity(_) => 0x12, + Self::EntityDestroy => 0x13, + Self::Entity(_) => 0x14, + Self::RelEntityMove(_) => 0x15, + Self::EntityLook(_) => 0x16, + Self::EntityMoveLook(_) => 0x17, + Self::EntityTeleport(_) => 0x18, + Self::EntityHeadRotation(_) => 0x19, + Self::EntityStatus(_) => 0x1A, + Self::AttachEntity(_) => 0x1B, + Self::EntityMetadata(_) => 0x1C, + Self::EntityEffect(_) => 0x1D, + Self::RemoveEntityEffect(_) => 0x1E, + Self::Experience(_) => 0x1F, + Self::UpdateAttributes(_) => 0x20, + Self::MapChunk(_) => 0x21, + Self::MultiBlockChange(_) => 0x22, + Self::BlockChange(_) => 0x23, + Self::BlockAction(_) => 0x24, + Self::BlockBreakAnimation(_) => 0x25, + Self::MapChunkBulk(_) => 0x26, + Self::Explosion(_) => 0x27, + Self::WorldEvent(_) => 0x28, + Self::NamedSoundEffect(_) => 0x29, + Self::WorldParticles(_) => 0x2A, + Self::GameStateChange(_) => 0x2B, + Self::SpawnEntityWeather(_) => 0x2C, + Self::OpenWindow(_) => 0x2D, + Self::ClientBoundCloseWindow(_) => 0x2E, + Self::SetSlot(_) => 0x2F, + Self::WindowItems(_) => 0x30, + Self::CraftProgressBar(_) => 0x31, + Self::ClientBoundTransaction(_) => 0x32, + Self::ClientBoundUpdateSign(_) => 0x33, + Self::Map(_) => 0x34, + Self::TileEntityData(_) => 0x35, + Self::OpenSignEntity(_) => 0x36, + Self::Statistics => 0x37, + Self::PlayerInfo(_) => 0x38, + Self::ClientBoundAbilities(_) => 0x39, + Self::ClientBoundTabComplete => 0x3A, + Self::ScoreboardObjective(_) => 0x3B, + Self::ScoreboardScore(_) => 0x3C, + Self::ScoreboardDisplayObjective(_) => 0x3D, + Self::ScoreboardTeam(_) => 0x3E, + Self::ClientBoundCustomPayload(_) => 0x3F, + Self::KickDisconnect(_) => 0x40, + Self::Difficulty(_) => 0x41, + Self::CombatEvent(_) => 0x42, + Self::Camera(_) => 0x43, + Self::WorldBorder(_) => 0x44, + Self::Title(_) => 0x45, + Self::SetCompression(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::ResourcePackSend(_) => 0x48, + Self::UpdateEntityNbt(_) => 0x49, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x01 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x02 => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x03 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x04 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x05 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x06 => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x07 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x08 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x09 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x0A => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x0B => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x0C => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x0D => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x0E => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x0F => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x10 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x11 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x12 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x13 => Ok(Self::EntityDestroy), + 0x14 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x15 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x16 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x17 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x18 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x19 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x1A => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1B => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x1C => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x1D => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x1E => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x1F => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x20 => { + let update_attributes = UpdateAttributes::decode(reader)?; + + Ok(Self::UpdateAttributes(update_attributes)) + } + 0x21 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x22 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x23 => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x24 => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x25 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x26 => { + let map_chunk_bulk = MapChunkBulk::decode(reader)?; + + Ok(Self::MapChunkBulk(map_chunk_bulk)) + } + 0x27 => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x28 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x29 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x2A => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x2B => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x2C => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x2D => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x2E => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2F => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x30 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x31 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x32 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x33 => { + let client_bound_update_sign = ClientBoundUpdateSign::decode(reader)?; + + Ok(Self::ClientBoundUpdateSign(client_bound_update_sign)) + } + 0x34 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x35 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x36 => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x37 => Ok(Self::Statistics), + 0x38 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x39 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x3A => Ok(Self::ClientBoundTabComplete), + 0x3B => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x3C => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x3D => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x3E => { + let scoreboard_team = ScoreboardTeam::decode(reader)?; + + Ok(Self::ScoreboardTeam(scoreboard_team)) + } + 0x3F => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x40 => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x41 => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x42 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x43 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x44 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let set_compression = SetCompression::decode(reader)?; + + Ok(Self::SetCompression(set_compression)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x49 => { + let update_entity_nbt = UpdateEntityNbt::decode(reader)?; + + Ok(Self::UpdateEntityNbt(update_entity_nbt)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i8, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn entity_equipment(entity_id: i32, slot: i16, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn client_bound_position(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, flags: i8) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + current_item: i16, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + current_item, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn spawn_entity( + entity_id: i32, + type_: i8, + x: i32, + y: i32, + z: i32, + pitch: i8, + yaw: i8, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + type_, + x, + y, + z, + pitch, + yaw, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_living( + entity_id: i32, + type_: u8, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: i32, y: i32, z: i32, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i8, d_y: i8, d_z: i8, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i8, + d_y: i8, + d_z: i8, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_teleport( + entity_id: i32, + x: i32, + y: i32, + z: i32, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32, leash: bool) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + leash, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: bool, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_attributes(entity_id: i32) -> Self { + let update_attributes = UpdateAttributes { entity_id }; + + Self::UpdateAttributes(update_attributes) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: u16, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn map_chunk_bulk(sky_light_sent: bool, data: Vec) -> Self { + let map_chunk_bulk = MapChunkBulk { + sky_light_sent, + data, + }; + + Self::MapChunkBulk(map_chunk_bulk) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn named_sound_effect( + sound_name: String, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: i32, y: i32, z: i32) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let client_bound_update_sign = ClientBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ClientBoundUpdateSign(client_bound_update_sign) + } + + pub fn map(item_damage: i32, scale: i8, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + columns, + }; + + Self::Map(map) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn scoreboard_team(team: String, mode: i8) -> Self { + let scoreboard_team = ScoreboardTeam { team, mode }; + + Self::ScoreboardTeam(scoreboard_team) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn set_compression(threshold: i32) -> Self { + let set_compression = SetCompression { threshold }; + + Self::SetCompression(set_compression) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn update_entity_nbt(entity_id: i32, tag: CompoundTag) -> Self { + let update_entity_nbt = UpdateEntityNbt { entity_id, tag }; + + Self::UpdateEntityNbt(update_entity_nbt) + } +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + pub direction: i8, + pub held_item: Option, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub block: Position, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + pub chat_flags: i8, + pub chat_colors: bool, + pub skin_parts: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub payload: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i8, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub current_item: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: i32, + pub y: i32, + pub z: i32, + pub pitch: i8, + pub yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: u8, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i8, + pub d_y: i8, + pub d_z: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i8, + pub d_y: i8, + pub d_z: i8, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, + pub leash: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + pub bit_map: u16, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct MapChunkBulk { + pub sky_light_sent: bool, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: i32, + pub y: i32, + pub z: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardTeam { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SetCompression { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateEntityNbt { + #[packet(with = "var_int")] + pub entity_id: i32, + pub tag: CompoundTag, +} diff --git a/protocol/src/version/v_1_8/handshake.rs b/protocol/src/version/v_1_8/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_8/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_8/login.rs b/protocol/src/version/v_1_8/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_8/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_8/mod.rs b/protocol/src/version/v_1_8/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_8/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_8/status.rs b/protocol/src/version/v_1_8/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_8/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_9/game.rs b/protocol/src/version/v_1_9/game.rs new file mode 100644 index 0000000..9a2ce42 --- /dev/null +++ b/protocol/src/version/v_1_9/game.rs @@ -0,0 +1,2719 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + ServerBoundUpdateSign(ServerBoundUpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::ServerBoundUpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let server_bound_update_sign = ServerBoundUpdateSign::decode(reader)?; + + Ok(Self::ServerBoundUpdateSign(server_bound_update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn server_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let server_bound_update_sign = ServerBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ServerBoundUpdateSign(server_bound_update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + ClientBoundUpdateSign(ClientBoundUpdateSign), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::ClientBoundUpdateSign(_) => 0x46, + Self::SoundEffect(_) => 0x47, + Self::PlayerlistHeader(_) => 0x48, + Self::Collect(_) => 0x49, + Self::EntityTeleport(_) => 0x4A, + Self::EntityUpdateAttributes(_) => 0x4B, + Self::EntityEffect(_) => 0x4C, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let client_bound_update_sign = ClientBoundUpdateSign::decode(reader)?; + + Ok(Self::ClientBoundUpdateSign(client_bound_update_sign)) + } + 0x47 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x48 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x49 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4A => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4B => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4C => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i8, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn client_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let client_bound_update_sign = ClientBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ClientBoundUpdateSign(client_bound_update_sign) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i8, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_9/handshake.rs b/protocol/src/version/v_1_9/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_9/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_9/login.rs b/protocol/src/version/v_1_9/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_9/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_9/mod.rs b/protocol/src/version/v_1_9/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_9/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_9/status.rs b/protocol/src/version/v_1_9/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_9/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_9_1_pre2/game.rs b/protocol/src/version/v_1_9_1_pre2/game.rs new file mode 100644 index 0000000..ae06599 --- /dev/null +++ b/protocol/src/version/v_1_9_1_pre2/game.rs @@ -0,0 +1,2719 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + ServerBoundUpdateSign(ServerBoundUpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::ServerBoundUpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let server_bound_update_sign = ServerBoundUpdateSign::decode(reader)?; + + Ok(Self::ServerBoundUpdateSign(server_bound_update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn server_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let server_bound_update_sign = ServerBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ServerBoundUpdateSign(server_bound_update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + ClientBoundUpdateSign(ClientBoundUpdateSign), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::ClientBoundUpdateSign(_) => 0x46, + Self::SoundEffect(_) => 0x47, + Self::PlayerlistHeader(_) => 0x48, + Self::Collect(_) => 0x49, + Self::EntityTeleport(_) => 0x4A, + Self::EntityUpdateAttributes(_) => 0x4B, + Self::EntityEffect(_) => 0x4C, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let client_bound_update_sign = ClientBoundUpdateSign::decode(reader)?; + + Ok(Self::ClientBoundUpdateSign(client_bound_update_sign)) + } + 0x47 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x48 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x49 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4A => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4B => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4C => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn client_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let client_bound_update_sign = ClientBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ClientBoundUpdateSign(client_bound_update_sign) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_9_1_pre2/handshake.rs b/protocol/src/version/v_1_9_1_pre2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_9_1_pre2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_9_1_pre2/login.rs b/protocol/src/version/v_1_9_1_pre2/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_9_1_pre2/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_9_1_pre2/mod.rs b/protocol/src/version/v_1_9_1_pre2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_9_1_pre2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_9_1_pre2/status.rs b/protocol/src/version/v_1_9_1_pre2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_9_1_pre2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_9_2/game.rs b/protocol/src/version/v_1_9_2/game.rs new file mode 100644 index 0000000..ae06599 --- /dev/null +++ b/protocol/src/version/v_1_9_2/game.rs @@ -0,0 +1,2719 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + ServerBoundUpdateSign(ServerBoundUpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::ServerBoundUpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let server_bound_update_sign = ServerBoundUpdateSign::decode(reader)?; + + Ok(Self::ServerBoundUpdateSign(server_bound_update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn server_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let server_bound_update_sign = ServerBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ServerBoundUpdateSign(server_bound_update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + ClientBoundUpdateSign(ClientBoundUpdateSign), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::ClientBoundUpdateSign(_) => 0x46, + Self::SoundEffect(_) => 0x47, + Self::PlayerlistHeader(_) => 0x48, + Self::Collect(_) => 0x49, + Self::EntityTeleport(_) => 0x4A, + Self::EntityUpdateAttributes(_) => 0x4B, + Self::EntityEffect(_) => 0x4C, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let client_bound_update_sign = ClientBoundUpdateSign::decode(reader)?; + + Ok(Self::ClientBoundUpdateSign(client_bound_update_sign)) + } + 0x47 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x48 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x49 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x4A => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4B => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4C => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn client_bound_update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let client_bound_update_sign = ClientBoundUpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::ClientBoundUpdateSign(client_bound_update_sign) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundUpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_9_2/handshake.rs b/protocol/src/version/v_1_9_2/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_9_2/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_9_2/login.rs b/protocol/src/version/v_1_9_2/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_9_2/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_9_2/mod.rs b/protocol/src/version/v_1_9_2/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_9_2/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_9_2/status.rs b/protocol/src/version/v_1_9_2/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_9_2/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_1_9_4/game.rs b/protocol/src/version/v_1_9_4/game.rs new file mode 100644 index 0000000..f229dba --- /dev/null +++ b/protocol/src/version/v_1_9_4/game.rs @@ -0,0 +1,2685 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::ServerBoundTabComplete(_) => 0x01, + Self::ServerBoundChat(_) => 0x02, + Self::ClientCommand(_) => 0x03, + Self::Settings(_) => 0x04, + Self::ServerBoundTransaction(_) => 0x05, + Self::EnchantItem(_) => 0x06, + Self::WindowClick(_) => 0x07, + Self::ServerBoundCloseWindow(_) => 0x08, + Self::ServerBoundCustomPayload(_) => 0x09, + Self::UseEntity(_) => 0x0A, + Self::ServerBoundKeepAlive(_) => 0x0B, + Self::ServerBoundPosition(_) => 0x0C, + Self::PositionLook(_) => 0x0D, + Self::Look(_) => 0x0E, + Self::Flying(_) => 0x0F, + Self::ServerBoundVehicleMove(_) => 0x10, + Self::SteerBoat(_) => 0x11, + Self::ServerBoundAbilities(_) => 0x12, + Self::BlockDig(_) => 0x13, + Self::EntityAction(_) => 0x14, + Self::SteerVehicle(_) => 0x15, + Self::ResourcePackReceive(_) => 0x16, + Self::ServerBoundHeldItemSlot(_) => 0x17, + Self::SetCreativeSlot(_) => 0x18, + Self::UpdateSign(_) => 0x19, + Self::ArmAnimation(_) => 0x1A, + Self::Spectate(_) => 0x1B, + Self::BlockPlace(_) => 0x1C, + Self::UseItem(_) => 0x1D, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x02 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x03 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x04 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x05 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x06 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x07 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x08 => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x09 => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0A => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0B => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x0C => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x0D => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x0E => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x0F => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x10 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x11 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x12 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x13 => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x14 => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x15 => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x16 => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x17 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x18 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x19 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x1A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x1B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x1C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x1D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn server_bound_tab_complete( + text: String, + assume_command: bool, + looked_at_block: Position, + ) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + text, + assume_command, + looked_at_block, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i32) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn resource_pack_receive(hash: String, result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { hash, result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + location: Position, + direction: i32, + hand: i32, + cursor_x: i8, + cursor_y: i8, + cursor_z: i8, + ) -> Self { + let block_place = BlockPlace { + location, + direction, + hand, + cursor_x, + cursor_y, + cursor_z, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete, + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + JoinGame(JoinGame), + Map(Map), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenSignEntity(OpenSignEntity), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + Bed(Bed), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::BlockBreakAnimation(_) => 0x08, + Self::TileEntityData(_) => 0x09, + Self::BlockAction(_) => 0x0A, + Self::BlockChange(_) => 0x0B, + Self::BossBar(_) => 0x0C, + Self::Difficulty(_) => 0x0D, + Self::ClientBoundTabComplete => 0x0E, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x11, + Self::ClientBoundCloseWindow(_) => 0x12, + Self::OpenWindow(_) => 0x13, + Self::WindowItems(_) => 0x14, + Self::CraftProgressBar(_) => 0x15, + Self::SetSlot(_) => 0x16, + Self::SetCooldown(_) => 0x17, + Self::ClientBoundCustomPayload(_) => 0x18, + Self::NamedSoundEffect(_) => 0x19, + Self::KickDisconnect(_) => 0x1A, + Self::EntityStatus(_) => 0x1B, + Self::Explosion(_) => 0x1C, + Self::UnloadChunk(_) => 0x1D, + Self::GameStateChange(_) => 0x1E, + Self::ClientBoundKeepAlive(_) => 0x1F, + Self::MapChunk(_) => 0x20, + Self::WorldEvent(_) => 0x21, + Self::WorldParticles(_) => 0x22, + Self::JoinGame(_) => 0x23, + Self::Map(_) => 0x24, + Self::RelEntityMove(_) => 0x25, + Self::EntityMoveLook(_) => 0x26, + Self::EntityLook(_) => 0x27, + Self::Entity(_) => 0x28, + Self::ClientBoundVehicleMove(_) => 0x29, + Self::OpenSignEntity(_) => 0x2A, + Self::ClientBoundAbilities(_) => 0x2B, + Self::CombatEvent(_) => 0x2C, + Self::PlayerInfo(_) => 0x2D, + Self::ClientBoundPosition(_) => 0x2E, + Self::Bed(_) => 0x2F, + Self::EntityDestroy => 0x30, + Self::RemoveEntityEffect(_) => 0x31, + Self::ResourcePackSend(_) => 0x32, + Self::Respawn(_) => 0x33, + Self::EntityHeadRotation(_) => 0x34, + Self::WorldBorder(_) => 0x35, + Self::Camera(_) => 0x36, + Self::ClientBoundHeldItemSlot(_) => 0x37, + Self::ScoreboardDisplayObjective(_) => 0x38, + Self::EntityMetadata(_) => 0x39, + Self::AttachEntity(_) => 0x3A, + Self::EntityVelocity(_) => 0x3B, + Self::EntityEquipment(_) => 0x3C, + Self::Experience(_) => 0x3D, + Self::UpdateHealth(_) => 0x3E, + Self::ScoreboardObjective(_) => 0x3F, + Self::SetPassengers(_) => 0x40, + Self::Teams(_) => 0x41, + Self::ScoreboardScore(_) => 0x42, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x44, + Self::Title(_) => 0x45, + Self::SoundEffect(_) => 0x46, + Self::PlayerlistHeader(_) => 0x47, + Self::Collect(_) => 0x48, + Self::EntityTeleport(_) => 0x49, + Self::EntityUpdateAttributes(_) => 0x4A, + Self::EntityEffect(_) => 0x4B, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x08 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x09 => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0A => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0B => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0C => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0D => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x0E => Ok(Self::ClientBoundTabComplete), + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x11 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x12 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x13 => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x14 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x15 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x16 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x17 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x18 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x19 => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1A => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1B => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1C => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1D => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1E => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x1F => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x20 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x21 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x22 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x23 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x24 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x25 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x26 => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x27 => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x28 => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x29 => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2A => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x2B => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x2C => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x2D => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x2E => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x2F => { + let bed = Bed::decode(reader)?; + + Ok(Self::Bed(bed)) + } + 0x30 => Ok(Self::EntityDestroy), + 0x31 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x32 => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x33 => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x34 => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x35 => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x36 => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x37 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x38 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x39 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x3A => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x3B => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x3C => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x3D => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x3E => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x3F => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x40 => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x41 => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x42 => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x44 => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x45 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x46 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x47 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x48 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x49 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x4A => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x4B => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i8, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: u8, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + metadata: Metadata, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + metadata, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: String, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + metadata: Metadata, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + metadata, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8) -> Self { + let difficulty = Difficulty { difficulty }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete() -> Self { + Self::ClientBoundTabComplete + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window( + window_id: u8, + inventory_type: String, + window_title: String, + slot_count: u8, + ) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + slot_count, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn client_bound_keep_alive(keep_alive_id: i32) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk(x: i32, z: i32, ground_up: bool, bit_map: i32, chunk_data: Vec) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f32, + y: f32, + z: f32, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + }; + + Self::WorldParticles(world_particles) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + difficulty: u8, + max_players: u8, + level_type: String, + reduced_debug_info: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + difficulty, + max_players, + level_type, + reduced_debug_info, + }; + + Self::JoinGame(join_game) + } + + pub fn map(item_damage: i32, scale: i8, tracking_position: bool, columns: i8) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + columns, + }; + + Self::Map(map) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn bed(entity_id: i32, location: Position) -> Self { + let bed = Bed { + entity_id, + location, + }; + + Self::Bed(bed) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, difficulty: u8, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + difficulty, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: u8, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect(collected_entity_id: i32, collector_entity_id: i32) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + pub text: String, + pub assume_command: bool, + pub looked_at_block: Position, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + pub hash: String, + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + #[packet(with = "var_int")] + pub hand: i32, + pub cursor_x: i8, + pub cursor_y: i8, + pub cursor_z: i8, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub type_: u8, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + pub title: String, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + pub window_id: u8, + pub inventory_type: String, + pub window_title: String, + pub slot_count: u8, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + #[packet(with = "var_int")] + pub keep_alive_id: i32, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f32, + pub y: f32, + pub z: f32, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub difficulty: u8, + pub max_players: u8, + pub level_type: String, + pub reduced_debug_info: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Bed { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub difficulty: u8, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: u8, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} diff --git a/protocol/src/version/v_1_9_4/handshake.rs b/protocol/src/version/v_1_9_4/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_1_9_4/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_1_9_4/login.rs b/protocol/src/version/v_1_9_4/login.rs new file mode 100644 index 0000000..3de55c1 --- /dev/null +++ b/protocol/src/version/v_1_9_4/login.rs @@ -0,0 +1,162 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: String, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: String, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} diff --git a/protocol/src/version/v_1_9_4/mod.rs b/protocol/src/version/v_1_9_4/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_1_9_4/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_1_9_4/status.rs b/protocol/src/version/v_1_9_4/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_1_9_4/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +} diff --git a/protocol/src/version/v_20w13b/game.rs b/protocol/src/version/v_20w13b/game.rs new file mode 100644 index 0000000..b11ebad --- /dev/null +++ b/protocol/src/version/v_20w13b/game.rs @@ -0,0 +1,3579 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use crate::data::game::*; +use nbt::CompoundTag; +use uuid::Uuid; + +pub enum ServerBoundGamePacket { + TeleportConfirm(TeleportConfirm), + QueryBlockNbt(QueryBlockNbt), + SetDifficulty(SetDifficulty), + EditBook(EditBook), + QueryEntityNbt(QueryEntityNbt), + PickItem(PickItem), + NameItem(NameItem), + SelectTrade(SelectTrade), + SetBeaconEffect(SetBeaconEffect), + UpdateCommandBlock(UpdateCommandBlock), + UpdateCommandBlockMinecart(UpdateCommandBlockMinecart), + UpdateStructureBlock(UpdateStructureBlock), + ServerBoundTabComplete(ServerBoundTabComplete), + ServerBoundChat(ServerBoundChat), + ClientCommand(ClientCommand), + Settings(Settings), + ServerBoundTransaction(ServerBoundTransaction), + EnchantItem(EnchantItem), + WindowClick(WindowClick), + ServerBoundCloseWindow(ServerBoundCloseWindow), + ServerBoundCustomPayload(ServerBoundCustomPayload), + UseEntity(UseEntity), + ServerBoundKeepAlive(ServerBoundKeepAlive), + LockDifficulty(LockDifficulty), + ServerBoundPosition(ServerBoundPosition), + PositionLook(PositionLook), + Look(Look), + Flying(Flying), + ServerBoundVehicleMove(ServerBoundVehicleMove), + SteerBoat(SteerBoat), + CraftRecipeRequest(CraftRecipeRequest), + ServerBoundAbilities(ServerBoundAbilities), + BlockDig(BlockDig), + EntityAction(EntityAction), + SteerVehicle(SteerVehicle), + CraftingBookData(CraftingBookData), + ResourcePackReceive(ResourcePackReceive), + ServerBoundHeldItemSlot(ServerBoundHeldItemSlot), + SetCreativeSlot(SetCreativeSlot), + UpdateJigsawBlock(UpdateJigsawBlock), + UpdateSign(UpdateSign), + ArmAnimation(ArmAnimation), + Spectate(Spectate), + BlockPlace(BlockPlace), + UseItem(UseItem), + AdvancementTab(AdvancementTab), +} + +impl ServerBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::TeleportConfirm(_) => 0x00, + Self::QueryBlockNbt(_) => 0x01, + Self::SetDifficulty(_) => 0x02, + Self::EditBook(_) => 0x0C, + Self::QueryEntityNbt(_) => 0x0D, + Self::PickItem(_) => 0x17, + Self::NameItem(_) => 0x1E, + Self::SelectTrade(_) => 0x21, + Self::SetBeaconEffect(_) => 0x22, + Self::UpdateCommandBlock(_) => 0x24, + Self::UpdateCommandBlockMinecart(_) => 0x25, + Self::UpdateStructureBlock(_) => 0x28, + Self::ServerBoundTabComplete(_) => 0x06, + Self::ServerBoundChat(_) => 0x03, + Self::ClientCommand(_) => 0x04, + Self::Settings(_) => 0x05, + Self::ServerBoundTransaction(_) => 0x07, + Self::EnchantItem(_) => 0x08, + Self::WindowClick(_) => 0x09, + Self::ServerBoundCloseWindow(_) => 0x0A, + Self::ServerBoundCustomPayload(_) => 0x0B, + Self::UseEntity(_) => 0x0E, + Self::ServerBoundKeepAlive(_) => 0x0F, + Self::LockDifficulty(_) => 0x10, + Self::ServerBoundPosition(_) => 0x11, + Self::PositionLook(_) => 0x12, + Self::Look(_) => 0x13, + Self::Flying(_) => 0x14, + Self::ServerBoundVehicleMove(_) => 0x15, + Self::SteerBoat(_) => 0x16, + Self::CraftRecipeRequest(_) => 0x18, + Self::ServerBoundAbilities(_) => 0x19, + Self::BlockDig(_) => 0x1A, + Self::EntityAction(_) => 0x1B, + Self::SteerVehicle(_) => 0x1C, + Self::CraftingBookData(_) => 0x1D, + Self::ResourcePackReceive(_) => 0x1F, + Self::ServerBoundHeldItemSlot(_) => 0x23, + Self::SetCreativeSlot(_) => 0x26, + Self::UpdateJigsawBlock(_) => 0x27, + Self::UpdateSign(_) => 0x29, + Self::ArmAnimation(_) => 0x2A, + Self::Spectate(_) => 0x2B, + Self::BlockPlace(_) => 0x2C, + Self::UseItem(_) => 0x2D, + Self::AdvancementTab(_) => 0x20, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let teleport_confirm = TeleportConfirm::decode(reader)?; + + Ok(Self::TeleportConfirm(teleport_confirm)) + } + 0x01 => { + let query_block_nbt = QueryBlockNbt::decode(reader)?; + + Ok(Self::QueryBlockNbt(query_block_nbt)) + } + 0x02 => { + let set_difficulty = SetDifficulty::decode(reader)?; + + Ok(Self::SetDifficulty(set_difficulty)) + } + 0x0C => { + let edit_book = EditBook::decode(reader)?; + + Ok(Self::EditBook(edit_book)) + } + 0x0D => { + let query_entity_nbt = QueryEntityNbt::decode(reader)?; + + Ok(Self::QueryEntityNbt(query_entity_nbt)) + } + 0x17 => { + let pick_item = PickItem::decode(reader)?; + + Ok(Self::PickItem(pick_item)) + } + 0x1E => { + let name_item = NameItem::decode(reader)?; + + Ok(Self::NameItem(name_item)) + } + 0x21 => { + let select_trade = SelectTrade::decode(reader)?; + + Ok(Self::SelectTrade(select_trade)) + } + 0x22 => { + let set_beacon_effect = SetBeaconEffect::decode(reader)?; + + Ok(Self::SetBeaconEffect(set_beacon_effect)) + } + 0x24 => { + let update_command_block = UpdateCommandBlock::decode(reader)?; + + Ok(Self::UpdateCommandBlock(update_command_block)) + } + 0x25 => { + let update_command_block_minecart = UpdateCommandBlockMinecart::decode(reader)?; + + Ok(Self::UpdateCommandBlockMinecart( + update_command_block_minecart, + )) + } + 0x28 => { + let update_structure_block = UpdateStructureBlock::decode(reader)?; + + Ok(Self::UpdateStructureBlock(update_structure_block)) + } + 0x06 => { + let server_bound_tab_complete = ServerBoundTabComplete::decode(reader)?; + + Ok(Self::ServerBoundTabComplete(server_bound_tab_complete)) + } + 0x03 => { + let server_bound_chat = ServerBoundChat::decode(reader)?; + + Ok(Self::ServerBoundChat(server_bound_chat)) + } + 0x04 => { + let client_command = ClientCommand::decode(reader)?; + + Ok(Self::ClientCommand(client_command)) + } + 0x05 => { + let settings = Settings::decode(reader)?; + + Ok(Self::Settings(settings)) + } + 0x07 => { + let server_bound_transaction = ServerBoundTransaction::decode(reader)?; + + Ok(Self::ServerBoundTransaction(server_bound_transaction)) + } + 0x08 => { + let enchant_item = EnchantItem::decode(reader)?; + + Ok(Self::EnchantItem(enchant_item)) + } + 0x09 => { + let window_click = WindowClick::decode(reader)?; + + Ok(Self::WindowClick(window_click)) + } + 0x0A => { + let server_bound_close_window = ServerBoundCloseWindow::decode(reader)?; + + Ok(Self::ServerBoundCloseWindow(server_bound_close_window)) + } + 0x0B => { + let server_bound_custom_payload = ServerBoundCustomPayload::decode(reader)?; + + Ok(Self::ServerBoundCustomPayload(server_bound_custom_payload)) + } + 0x0E => { + let use_entity = UseEntity::decode(reader)?; + + Ok(Self::UseEntity(use_entity)) + } + 0x0F => { + let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?; + + Ok(Self::ServerBoundKeepAlive(server_bound_keep_alive)) + } + 0x10 => { + let lock_difficulty = LockDifficulty::decode(reader)?; + + Ok(Self::LockDifficulty(lock_difficulty)) + } + 0x11 => { + let server_bound_position = ServerBoundPosition::decode(reader)?; + + Ok(Self::ServerBoundPosition(server_bound_position)) + } + 0x12 => { + let position_look = PositionLook::decode(reader)?; + + Ok(Self::PositionLook(position_look)) + } + 0x13 => { + let look = Look::decode(reader)?; + + Ok(Self::Look(look)) + } + 0x14 => { + let flying = Flying::decode(reader)?; + + Ok(Self::Flying(flying)) + } + 0x15 => { + let server_bound_vehicle_move = ServerBoundVehicleMove::decode(reader)?; + + Ok(Self::ServerBoundVehicleMove(server_bound_vehicle_move)) + } + 0x16 => { + let steer_boat = SteerBoat::decode(reader)?; + + Ok(Self::SteerBoat(steer_boat)) + } + 0x18 => { + let craft_recipe_request = CraftRecipeRequest::decode(reader)?; + + Ok(Self::CraftRecipeRequest(craft_recipe_request)) + } + 0x19 => { + let server_bound_abilities = ServerBoundAbilities::decode(reader)?; + + Ok(Self::ServerBoundAbilities(server_bound_abilities)) + } + 0x1A => { + let block_dig = BlockDig::decode(reader)?; + + Ok(Self::BlockDig(block_dig)) + } + 0x1B => { + let entity_action = EntityAction::decode(reader)?; + + Ok(Self::EntityAction(entity_action)) + } + 0x1C => { + let steer_vehicle = SteerVehicle::decode(reader)?; + + Ok(Self::SteerVehicle(steer_vehicle)) + } + 0x1D => { + let crafting_book_data = CraftingBookData::decode(reader)?; + + Ok(Self::CraftingBookData(crafting_book_data)) + } + 0x1F => { + let resource_pack_receive = ResourcePackReceive::decode(reader)?; + + Ok(Self::ResourcePackReceive(resource_pack_receive)) + } + 0x23 => { + let server_bound_held_item_slot = ServerBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ServerBoundHeldItemSlot(server_bound_held_item_slot)) + } + 0x26 => { + let set_creative_slot = SetCreativeSlot::decode(reader)?; + + Ok(Self::SetCreativeSlot(set_creative_slot)) + } + 0x27 => { + let update_jigsaw_block = UpdateJigsawBlock::decode(reader)?; + + Ok(Self::UpdateJigsawBlock(update_jigsaw_block)) + } + 0x29 => { + let update_sign = UpdateSign::decode(reader)?; + + Ok(Self::UpdateSign(update_sign)) + } + 0x2A => { + let arm_animation = ArmAnimation::decode(reader)?; + + Ok(Self::ArmAnimation(arm_animation)) + } + 0x2B => { + let spectate = Spectate::decode(reader)?; + + Ok(Self::Spectate(spectate)) + } + 0x2C => { + let block_place = BlockPlace::decode(reader)?; + + Ok(Self::BlockPlace(block_place)) + } + 0x2D => { + let use_item = UseItem::decode(reader)?; + + Ok(Self::UseItem(use_item)) + } + 0x20 => { + let advancement_tab = AdvancementTab::decode(reader)?; + + Ok(Self::AdvancementTab(advancement_tab)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn teleport_confirm(teleport_id: i32) -> Self { + let teleport_confirm = TeleportConfirm { teleport_id }; + + Self::TeleportConfirm(teleport_confirm) + } + + pub fn query_block_nbt(transaction_id: i32, location: Position) -> Self { + let query_block_nbt = QueryBlockNbt { + transaction_id, + location, + }; + + Self::QueryBlockNbt(query_block_nbt) + } + + pub fn set_difficulty(new_difficulty: u8) -> Self { + let set_difficulty = SetDifficulty { new_difficulty }; + + Self::SetDifficulty(set_difficulty) + } + + pub fn edit_book(new_book: Option, signing: bool, hand: i32) -> Self { + let edit_book = EditBook { + new_book, + signing, + hand, + }; + + Self::EditBook(edit_book) + } + + pub fn query_entity_nbt(transaction_id: i32, entity_id: i32) -> Self { + let query_entity_nbt = QueryEntityNbt { + transaction_id, + entity_id, + }; + + Self::QueryEntityNbt(query_entity_nbt) + } + + pub fn pick_item(slot: i32) -> Self { + let pick_item = PickItem { slot }; + + Self::PickItem(pick_item) + } + + pub fn name_item(name: String) -> Self { + let name_item = NameItem { name }; + + Self::NameItem(name_item) + } + + pub fn select_trade(slot: i32) -> Self { + let select_trade = SelectTrade { slot }; + + Self::SelectTrade(select_trade) + } + + pub fn set_beacon_effect(primary_effect: i32, secondary_effect: i32) -> Self { + let set_beacon_effect = SetBeaconEffect { + primary_effect, + secondary_effect, + }; + + Self::SetBeaconEffect(set_beacon_effect) + } + + pub fn update_command_block(location: Position, command: String, mode: i32, flags: u8) -> Self { + let update_command_block = UpdateCommandBlock { + location, + command, + mode, + flags, + }; + + Self::UpdateCommandBlock(update_command_block) + } + + pub fn update_command_block_minecart( + entity_id: i32, + command: String, + track_output: bool, + ) -> Self { + let update_command_block_minecart = UpdateCommandBlockMinecart { + entity_id, + command, + track_output, + }; + + Self::UpdateCommandBlockMinecart(update_command_block_minecart) + } + + pub fn update_structure_block( + location: Position, + action: i32, + mode: i32, + name: String, + offset_x: u8, + offset_y: u8, + offset_z: u8, + size_x: u8, + size_y: u8, + size_z: u8, + mirror: i32, + rotation: i32, + metadata: String, + integrity: f32, + seed: i32, + flags: u8, + ) -> Self { + let update_structure_block = UpdateStructureBlock { + location, + action, + mode, + name, + offset_x, + offset_y, + offset_z, + size_x, + size_y, + size_z, + mirror, + rotation, + metadata, + integrity, + seed, + flags, + }; + + Self::UpdateStructureBlock(update_structure_block) + } + + pub fn server_bound_tab_complete(transaction_id: i32, text: String) -> Self { + let server_bound_tab_complete = ServerBoundTabComplete { + transaction_id, + text, + }; + + Self::ServerBoundTabComplete(server_bound_tab_complete) + } + + pub fn server_bound_chat(message: String) -> Self { + let server_bound_chat = ServerBoundChat { message }; + + Self::ServerBoundChat(server_bound_chat) + } + + pub fn client_command(action_id: i32) -> Self { + let client_command = ClientCommand { action_id }; + + Self::ClientCommand(client_command) + } + + pub fn settings( + locale: String, + view_distance: i8, + chat_flags: i32, + chat_colors: bool, + skin_parts: u8, + main_hand: i32, + ) -> Self { + let settings = Settings { + locale, + view_distance, + chat_flags, + chat_colors, + skin_parts, + main_hand, + }; + + Self::Settings(settings) + } + + pub fn server_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let server_bound_transaction = ServerBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ServerBoundTransaction(server_bound_transaction) + } + + pub fn enchant_item(window_id: i8, enchantment: i8) -> Self { + let enchant_item = EnchantItem { + window_id, + enchantment, + }; + + Self::EnchantItem(enchant_item) + } + + pub fn window_click( + window_id: u8, + slot: i16, + mouse_button: i8, + action: i16, + mode: i8, + item: Option, + ) -> Self { + let window_click = WindowClick { + window_id, + slot, + mouse_button, + action, + mode, + item, + }; + + Self::WindowClick(window_click) + } + + pub fn server_bound_close_window(window_id: u8) -> Self { + let server_bound_close_window = ServerBoundCloseWindow { window_id }; + + Self::ServerBoundCloseWindow(server_bound_close_window) + } + + pub fn server_bound_custom_payload(channel: String, data: Vec) -> Self { + let server_bound_custom_payload = ServerBoundCustomPayload { channel, data }; + + Self::ServerBoundCustomPayload(server_bound_custom_payload) + } + + pub fn use_entity(target: i32, mouse: i32) -> Self { + let use_entity = UseEntity { target, mouse }; + + Self::UseEntity(use_entity) + } + + pub fn server_bound_keep_alive(keep_alive_id: i64) -> Self { + let server_bound_keep_alive = ServerBoundKeepAlive { keep_alive_id }; + + Self::ServerBoundKeepAlive(server_bound_keep_alive) + } + + pub fn lock_difficulty(locked: bool) -> Self { + let lock_difficulty = LockDifficulty { locked }; + + Self::LockDifficulty(lock_difficulty) + } + + pub fn server_bound_position(x: f64, y: f64, z: f64, on_ground: bool) -> Self { + let server_bound_position = ServerBoundPosition { x, y, z, on_ground }; + + Self::ServerBoundPosition(server_bound_position) + } + + pub fn position_look(x: f64, y: f64, z: f64, yaw: f32, pitch: f32, on_ground: bool) -> Self { + let position_look = PositionLook { + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::PositionLook(position_look) + } + + pub fn look(yaw: f32, pitch: f32, on_ground: bool) -> Self { + let look = Look { + yaw, + pitch, + on_ground, + }; + + Self::Look(look) + } + + pub fn flying(on_ground: bool) -> Self { + let flying = Flying { on_ground }; + + Self::Flying(flying) + } + + pub fn server_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let server_bound_vehicle_move = ServerBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ServerBoundVehicleMove(server_bound_vehicle_move) + } + + pub fn steer_boat(left_paddle: bool, right_paddle: bool) -> Self { + let steer_boat = SteerBoat { + left_paddle, + right_paddle, + }; + + Self::SteerBoat(steer_boat) + } + + pub fn craft_recipe_request(window_id: i8, recipe: String, make_all: bool) -> Self { + let craft_recipe_request = CraftRecipeRequest { + window_id, + recipe, + make_all, + }; + + Self::CraftRecipeRequest(craft_recipe_request) + } + + pub fn server_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let server_bound_abilities = ServerBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ServerBoundAbilities(server_bound_abilities) + } + + pub fn block_dig(status: i8, location: Position, face: i8) -> Self { + let block_dig = BlockDig { + status, + location, + face, + }; + + Self::BlockDig(block_dig) + } + + pub fn entity_action(entity_id: i32, action_id: i32, jump_boost: i32) -> Self { + let entity_action = EntityAction { + entity_id, + action_id, + jump_boost, + }; + + Self::EntityAction(entity_action) + } + + pub fn steer_vehicle(sideways: f32, forward: f32, jump: u8) -> Self { + let steer_vehicle = SteerVehicle { + sideways, + forward, + jump, + }; + + Self::SteerVehicle(steer_vehicle) + } + + pub fn crafting_book_data(type_: i32) -> Self { + let crafting_book_data = CraftingBookData { type_ }; + + Self::CraftingBookData(crafting_book_data) + } + + pub fn resource_pack_receive(result: i32) -> Self { + let resource_pack_receive = ResourcePackReceive { result }; + + Self::ResourcePackReceive(resource_pack_receive) + } + + pub fn server_bound_held_item_slot(slot_id: i16) -> Self { + let server_bound_held_item_slot = ServerBoundHeldItemSlot { slot_id }; + + Self::ServerBoundHeldItemSlot(server_bound_held_item_slot) + } + + pub fn set_creative_slot(slot: i16, item: Option) -> Self { + let set_creative_slot = SetCreativeSlot { slot, item }; + + Self::SetCreativeSlot(set_creative_slot) + } + + pub fn update_jigsaw_block( + location: Position, + name: String, + target: String, + pool: String, + final_state: String, + joint_type: String, + ) -> Self { + let update_jigsaw_block = UpdateJigsawBlock { + location, + name, + target, + pool, + final_state, + joint_type, + }; + + Self::UpdateJigsawBlock(update_jigsaw_block) + } + + pub fn update_sign( + location: Position, + text1: String, + text2: String, + text3: String, + text4: String, + ) -> Self { + let update_sign = UpdateSign { + location, + text1, + text2, + text3, + text4, + }; + + Self::UpdateSign(update_sign) + } + + pub fn arm_animation(hand: i32) -> Self { + let arm_animation = ArmAnimation { hand }; + + Self::ArmAnimation(arm_animation) + } + + pub fn spectate(target: Uuid) -> Self { + let spectate = Spectate { target }; + + Self::Spectate(spectate) + } + + pub fn block_place( + hand: i32, + location: Position, + direction: i32, + cursor_x: f32, + cursor_y: f32, + cursor_z: f32, + inside_block: bool, + ) -> Self { + let block_place = BlockPlace { + hand, + location, + direction, + cursor_x, + cursor_y, + cursor_z, + inside_block, + }; + + Self::BlockPlace(block_place) + } + + pub fn use_item(hand: i32) -> Self { + let use_item = UseItem { hand }; + + Self::UseItem(use_item) + } + + pub fn advancement_tab(action: i32) -> Self { + let advancement_tab = AdvancementTab { action }; + + Self::AdvancementTab(advancement_tab) + } +} + +pub enum ClientBoundGamePacket { + SpawnEntity(SpawnEntity), + SpawnEntityExperienceOrb(SpawnEntityExperienceOrb), + SpawnEntityWeather(SpawnEntityWeather), + SpawnEntityLiving(SpawnEntityLiving), + SpawnEntityPainting(SpawnEntityPainting), + NamedEntitySpawn(NamedEntitySpawn), + Animation(Animation), + Statistics, + Advancements(Advancements), + BlockBreakAnimation(BlockBreakAnimation), + TileEntityData(TileEntityData), + BlockAction(BlockAction), + BlockChange(BlockChange), + BossBar(BossBar), + Difficulty(Difficulty), + ClientBoundTabComplete(ClientBoundTabComplete), + DeclareCommands(DeclareCommands), + FacePlayer(FacePlayer), + NbtQueryResponse(NbtQueryResponse), + ClientBoundChat(ClientBoundChat), + MultiBlockChange(MultiBlockChange), + ClientBoundTransaction(ClientBoundTransaction), + ClientBoundCloseWindow(ClientBoundCloseWindow), + OpenWindow(OpenWindow), + WindowItems(WindowItems), + CraftProgressBar(CraftProgressBar), + SetSlot(SetSlot), + SetCooldown(SetCooldown), + ClientBoundCustomPayload(ClientBoundCustomPayload), + NamedSoundEffect(NamedSoundEffect), + KickDisconnect(KickDisconnect), + EntityStatus(EntityStatus), + Explosion(Explosion), + UnloadChunk(UnloadChunk), + GameStateChange(GameStateChange), + OpenHorseWindow(OpenHorseWindow), + ClientBoundKeepAlive(ClientBoundKeepAlive), + MapChunk(MapChunk), + WorldEvent(WorldEvent), + WorldParticles(WorldParticles), + UpdateLight(UpdateLight), + JoinGame(JoinGame), + Map(Map), + TradeList(TradeList), + RelEntityMove(RelEntityMove), + EntityMoveLook(EntityMoveLook), + EntityLook(EntityLook), + Entity(Entity), + ClientBoundVehicleMove(ClientBoundVehicleMove), + OpenBook(OpenBook), + OpenSignEntity(OpenSignEntity), + CraftRecipeResponse(CraftRecipeResponse), + ClientBoundAbilities(ClientBoundAbilities), + CombatEvent(CombatEvent), + PlayerInfo(PlayerInfo), + ClientBoundPosition(ClientBoundPosition), + UnlockRecipes(UnlockRecipes), + EntityDestroy, + RemoveEntityEffect(RemoveEntityEffect), + ResourcePackSend(ResourcePackSend), + Respawn(Respawn), + EntityHeadRotation(EntityHeadRotation), + WorldBorder(WorldBorder), + Camera(Camera), + ClientBoundHeldItemSlot(ClientBoundHeldItemSlot), + UpdateViewPosition(UpdateViewPosition), + UpdateViewDistance(UpdateViewDistance), + ScoreboardDisplayObjective(ScoreboardDisplayObjective), + EntityMetadata(EntityMetadata), + AttachEntity(AttachEntity), + EntityVelocity(EntityVelocity), + EntityEquipment(EntityEquipment), + Experience(Experience), + UpdateHealth(UpdateHealth), + ScoreboardObjective(ScoreboardObjective), + SetPassengers(SetPassengers), + Teams(Teams), + ScoreboardScore(ScoreboardScore), + SpawnPosition(SpawnPosition), + UpdateTime(UpdateTime), + Title(Title), + EntitySoundEffect(EntitySoundEffect), + StopSound(StopSound), + SoundEffect(SoundEffect), + PlayerlistHeader(PlayerlistHeader), + Collect(Collect), + EntityTeleport(EntityTeleport), + EntityUpdateAttributes(EntityUpdateAttributes), + EntityEffect(EntityEffect), + SelectAdvancementTab(SelectAdvancementTab), + DeclareRecipes, + Tags(Tags), + AcknowledgePlayerDigging(AcknowledgePlayerDigging), +} + +impl ClientBoundGamePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SpawnEntity(_) => 0x00, + Self::SpawnEntityExperienceOrb(_) => 0x01, + Self::SpawnEntityWeather(_) => 0x02, + Self::SpawnEntityLiving(_) => 0x03, + Self::SpawnEntityPainting(_) => 0x04, + Self::NamedEntitySpawn(_) => 0x05, + Self::Animation(_) => 0x06, + Self::Statistics => 0x07, + Self::Advancements(_) => 0x58, + Self::BlockBreakAnimation(_) => 0x09, + Self::TileEntityData(_) => 0x0A, + Self::BlockAction(_) => 0x0B, + Self::BlockChange(_) => 0x0C, + Self::BossBar(_) => 0x0D, + Self::Difficulty(_) => 0x0E, + Self::ClientBoundTabComplete(_) => 0x11, + Self::DeclareCommands(_) => 0x12, + Self::FacePlayer(_) => 0x35, + Self::NbtQueryResponse(_) => 0x55, + Self::ClientBoundChat(_) => 0x0F, + Self::MultiBlockChange(_) => 0x10, + Self::ClientBoundTransaction(_) => 0x13, + Self::ClientBoundCloseWindow(_) => 0x14, + Self::OpenWindow(_) => 0x2F, + Self::WindowItems(_) => 0x15, + Self::CraftProgressBar(_) => 0x16, + Self::SetSlot(_) => 0x17, + Self::SetCooldown(_) => 0x18, + Self::ClientBoundCustomPayload(_) => 0x19, + Self::NamedSoundEffect(_) => 0x1A, + Self::KickDisconnect(_) => 0x1B, + Self::EntityStatus(_) => 0x1C, + Self::Explosion(_) => 0x1D, + Self::UnloadChunk(_) => 0x1E, + Self::GameStateChange(_) => 0x1F, + Self::OpenHorseWindow(_) => 0x20, + Self::ClientBoundKeepAlive(_) => 0x21, + Self::MapChunk(_) => 0x22, + Self::WorldEvent(_) => 0x23, + Self::WorldParticles(_) => 0x24, + Self::UpdateLight(_) => 0x25, + Self::JoinGame(_) => 0x26, + Self::Map(_) => 0x27, + Self::TradeList(_) => 0x28, + Self::RelEntityMove(_) => 0x29, + Self::EntityMoveLook(_) => 0x2A, + Self::EntityLook(_) => 0x2B, + Self::Entity(_) => 0x2C, + Self::ClientBoundVehicleMove(_) => 0x2D, + Self::OpenBook(_) => 0x2E, + Self::OpenSignEntity(_) => 0x30, + Self::CraftRecipeResponse(_) => 0x31, + Self::ClientBoundAbilities(_) => 0x32, + Self::CombatEvent(_) => 0x33, + Self::PlayerInfo(_) => 0x34, + Self::ClientBoundPosition(_) => 0x36, + Self::UnlockRecipes(_) => 0x37, + Self::EntityDestroy => 0x38, + Self::RemoveEntityEffect(_) => 0x39, + Self::ResourcePackSend(_) => 0x3A, + Self::Respawn(_) => 0x3B, + Self::EntityHeadRotation(_) => 0x3C, + Self::WorldBorder(_) => 0x3E, + Self::Camera(_) => 0x3F, + Self::ClientBoundHeldItemSlot(_) => 0x40, + Self::UpdateViewPosition(_) => 0x41, + Self::UpdateViewDistance(_) => 0x42, + Self::ScoreboardDisplayObjective(_) => 0x44, + Self::EntityMetadata(_) => 0x45, + Self::AttachEntity(_) => 0x46, + Self::EntityVelocity(_) => 0x47, + Self::EntityEquipment(_) => 0x48, + Self::Experience(_) => 0x49, + Self::UpdateHealth(_) => 0x4A, + Self::ScoreboardObjective(_) => 0x4B, + Self::SetPassengers(_) => 0x4C, + Self::Teams(_) => 0x4D, + Self::ScoreboardScore(_) => 0x4E, + Self::SpawnPosition(_) => 0x43, + Self::UpdateTime(_) => 0x4F, + Self::Title(_) => 0x50, + Self::EntitySoundEffect(_) => 0x51, + Self::StopSound(_) => 0x53, + Self::SoundEffect(_) => 0x52, + Self::PlayerlistHeader(_) => 0x54, + Self::Collect(_) => 0x56, + Self::EntityTeleport(_) => 0x57, + Self::EntityUpdateAttributes(_) => 0x59, + Self::EntityEffect(_) => 0x5A, + Self::SelectAdvancementTab(_) => 0x3D, + Self::DeclareRecipes => 0x5B, + Self::Tags(_) => 0x5C, + Self::AcknowledgePlayerDigging(_) => 0x08, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let spawn_entity = SpawnEntity::decode(reader)?; + + Ok(Self::SpawnEntity(spawn_entity)) + } + 0x01 => { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb::decode(reader)?; + + Ok(Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb)) + } + 0x02 => { + let spawn_entity_weather = SpawnEntityWeather::decode(reader)?; + + Ok(Self::SpawnEntityWeather(spawn_entity_weather)) + } + 0x03 => { + let spawn_entity_living = SpawnEntityLiving::decode(reader)?; + + Ok(Self::SpawnEntityLiving(spawn_entity_living)) + } + 0x04 => { + let spawn_entity_painting = SpawnEntityPainting::decode(reader)?; + + Ok(Self::SpawnEntityPainting(spawn_entity_painting)) + } + 0x05 => { + let named_entity_spawn = NamedEntitySpawn::decode(reader)?; + + Ok(Self::NamedEntitySpawn(named_entity_spawn)) + } + 0x06 => { + let animation = Animation::decode(reader)?; + + Ok(Self::Animation(animation)) + } + 0x07 => Ok(Self::Statistics), + 0x58 => { + let advancements = Advancements::decode(reader)?; + + Ok(Self::Advancements(advancements)) + } + 0x09 => { + let block_break_animation = BlockBreakAnimation::decode(reader)?; + + Ok(Self::BlockBreakAnimation(block_break_animation)) + } + 0x0A => { + let tile_entity_data = TileEntityData::decode(reader)?; + + Ok(Self::TileEntityData(tile_entity_data)) + } + 0x0B => { + let block_action = BlockAction::decode(reader)?; + + Ok(Self::BlockAction(block_action)) + } + 0x0C => { + let block_change = BlockChange::decode(reader)?; + + Ok(Self::BlockChange(block_change)) + } + 0x0D => { + let boss_bar = BossBar::decode(reader)?; + + Ok(Self::BossBar(boss_bar)) + } + 0x0E => { + let difficulty = Difficulty::decode(reader)?; + + Ok(Self::Difficulty(difficulty)) + } + 0x11 => { + let client_bound_tab_complete = ClientBoundTabComplete::decode(reader)?; + + Ok(Self::ClientBoundTabComplete(client_bound_tab_complete)) + } + 0x12 => { + let declare_commands = DeclareCommands::decode(reader)?; + + Ok(Self::DeclareCommands(declare_commands)) + } + 0x35 => { + let face_player = FacePlayer::decode(reader)?; + + Ok(Self::FacePlayer(face_player)) + } + 0x55 => { + let nbt_query_response = NbtQueryResponse::decode(reader)?; + + Ok(Self::NbtQueryResponse(nbt_query_response)) + } + 0x0F => { + let client_bound_chat = ClientBoundChat::decode(reader)?; + + Ok(Self::ClientBoundChat(client_bound_chat)) + } + 0x10 => { + let multi_block_change = MultiBlockChange::decode(reader)?; + + Ok(Self::MultiBlockChange(multi_block_change)) + } + 0x13 => { + let client_bound_transaction = ClientBoundTransaction::decode(reader)?; + + Ok(Self::ClientBoundTransaction(client_bound_transaction)) + } + 0x14 => { + let client_bound_close_window = ClientBoundCloseWindow::decode(reader)?; + + Ok(Self::ClientBoundCloseWindow(client_bound_close_window)) + } + 0x2F => { + let open_window = OpenWindow::decode(reader)?; + + Ok(Self::OpenWindow(open_window)) + } + 0x15 => { + let window_items = WindowItems::decode(reader)?; + + Ok(Self::WindowItems(window_items)) + } + 0x16 => { + let craft_progress_bar = CraftProgressBar::decode(reader)?; + + Ok(Self::CraftProgressBar(craft_progress_bar)) + } + 0x17 => { + let set_slot = SetSlot::decode(reader)?; + + Ok(Self::SetSlot(set_slot)) + } + 0x18 => { + let set_cooldown = SetCooldown::decode(reader)?; + + Ok(Self::SetCooldown(set_cooldown)) + } + 0x19 => { + let client_bound_custom_payload = ClientBoundCustomPayload::decode(reader)?; + + Ok(Self::ClientBoundCustomPayload(client_bound_custom_payload)) + } + 0x1A => { + let named_sound_effect = NamedSoundEffect::decode(reader)?; + + Ok(Self::NamedSoundEffect(named_sound_effect)) + } + 0x1B => { + let kick_disconnect = KickDisconnect::decode(reader)?; + + Ok(Self::KickDisconnect(kick_disconnect)) + } + 0x1C => { + let entity_status = EntityStatus::decode(reader)?; + + Ok(Self::EntityStatus(entity_status)) + } + 0x1D => { + let explosion = Explosion::decode(reader)?; + + Ok(Self::Explosion(explosion)) + } + 0x1E => { + let unload_chunk = UnloadChunk::decode(reader)?; + + Ok(Self::UnloadChunk(unload_chunk)) + } + 0x1F => { + let game_state_change = GameStateChange::decode(reader)?; + + Ok(Self::GameStateChange(game_state_change)) + } + 0x20 => { + let open_horse_window = OpenHorseWindow::decode(reader)?; + + Ok(Self::OpenHorseWindow(open_horse_window)) + } + 0x21 => { + let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?; + + Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive)) + } + 0x22 => { + let map_chunk = MapChunk::decode(reader)?; + + Ok(Self::MapChunk(map_chunk)) + } + 0x23 => { + let world_event = WorldEvent::decode(reader)?; + + Ok(Self::WorldEvent(world_event)) + } + 0x24 => { + let world_particles = WorldParticles::decode(reader)?; + + Ok(Self::WorldParticles(world_particles)) + } + 0x25 => { + let update_light = UpdateLight::decode(reader)?; + + Ok(Self::UpdateLight(update_light)) + } + 0x26 => { + let join_game = JoinGame::decode(reader)?; + + Ok(Self::JoinGame(join_game)) + } + 0x27 => { + let map = Map::decode(reader)?; + + Ok(Self::Map(map)) + } + 0x28 => { + let trade_list = TradeList::decode(reader)?; + + Ok(Self::TradeList(trade_list)) + } + 0x29 => { + let rel_entity_move = RelEntityMove::decode(reader)?; + + Ok(Self::RelEntityMove(rel_entity_move)) + } + 0x2A => { + let entity_move_look = EntityMoveLook::decode(reader)?; + + Ok(Self::EntityMoveLook(entity_move_look)) + } + 0x2B => { + let entity_look = EntityLook::decode(reader)?; + + Ok(Self::EntityLook(entity_look)) + } + 0x2C => { + let entity = Entity::decode(reader)?; + + Ok(Self::Entity(entity)) + } + 0x2D => { + let client_bound_vehicle_move = ClientBoundVehicleMove::decode(reader)?; + + Ok(Self::ClientBoundVehicleMove(client_bound_vehicle_move)) + } + 0x2E => { + let open_book = OpenBook::decode(reader)?; + + Ok(Self::OpenBook(open_book)) + } + 0x30 => { + let open_sign_entity = OpenSignEntity::decode(reader)?; + + Ok(Self::OpenSignEntity(open_sign_entity)) + } + 0x31 => { + let craft_recipe_response = CraftRecipeResponse::decode(reader)?; + + Ok(Self::CraftRecipeResponse(craft_recipe_response)) + } + 0x32 => { + let client_bound_abilities = ClientBoundAbilities::decode(reader)?; + + Ok(Self::ClientBoundAbilities(client_bound_abilities)) + } + 0x33 => { + let combat_event = CombatEvent::decode(reader)?; + + Ok(Self::CombatEvent(combat_event)) + } + 0x34 => { + let player_info = PlayerInfo::decode(reader)?; + + Ok(Self::PlayerInfo(player_info)) + } + 0x36 => { + let client_bound_position = ClientBoundPosition::decode(reader)?; + + Ok(Self::ClientBoundPosition(client_bound_position)) + } + 0x37 => { + let unlock_recipes = UnlockRecipes::decode(reader)?; + + Ok(Self::UnlockRecipes(unlock_recipes)) + } + 0x38 => Ok(Self::EntityDestroy), + 0x39 => { + let remove_entity_effect = RemoveEntityEffect::decode(reader)?; + + Ok(Self::RemoveEntityEffect(remove_entity_effect)) + } + 0x3A => { + let resource_pack_send = ResourcePackSend::decode(reader)?; + + Ok(Self::ResourcePackSend(resource_pack_send)) + } + 0x3B => { + let respawn = Respawn::decode(reader)?; + + Ok(Self::Respawn(respawn)) + } + 0x3C => { + let entity_head_rotation = EntityHeadRotation::decode(reader)?; + + Ok(Self::EntityHeadRotation(entity_head_rotation)) + } + 0x3E => { + let world_border = WorldBorder::decode(reader)?; + + Ok(Self::WorldBorder(world_border)) + } + 0x3F => { + let camera = Camera::decode(reader)?; + + Ok(Self::Camera(camera)) + } + 0x40 => { + let client_bound_held_item_slot = ClientBoundHeldItemSlot::decode(reader)?; + + Ok(Self::ClientBoundHeldItemSlot(client_bound_held_item_slot)) + } + 0x41 => { + let update_view_position = UpdateViewPosition::decode(reader)?; + + Ok(Self::UpdateViewPosition(update_view_position)) + } + 0x42 => { + let update_view_distance = UpdateViewDistance::decode(reader)?; + + Ok(Self::UpdateViewDistance(update_view_distance)) + } + 0x44 => { + let scoreboard_display_objective = ScoreboardDisplayObjective::decode(reader)?; + + Ok(Self::ScoreboardDisplayObjective( + scoreboard_display_objective, + )) + } + 0x45 => { + let entity_metadata = EntityMetadata::decode(reader)?; + + Ok(Self::EntityMetadata(entity_metadata)) + } + 0x46 => { + let attach_entity = AttachEntity::decode(reader)?; + + Ok(Self::AttachEntity(attach_entity)) + } + 0x47 => { + let entity_velocity = EntityVelocity::decode(reader)?; + + Ok(Self::EntityVelocity(entity_velocity)) + } + 0x48 => { + let entity_equipment = EntityEquipment::decode(reader)?; + + Ok(Self::EntityEquipment(entity_equipment)) + } + 0x49 => { + let experience = Experience::decode(reader)?; + + Ok(Self::Experience(experience)) + } + 0x4A => { + let update_health = UpdateHealth::decode(reader)?; + + Ok(Self::UpdateHealth(update_health)) + } + 0x4B => { + let scoreboard_objective = ScoreboardObjective::decode(reader)?; + + Ok(Self::ScoreboardObjective(scoreboard_objective)) + } + 0x4C => { + let set_passengers = SetPassengers::decode(reader)?; + + Ok(Self::SetPassengers(set_passengers)) + } + 0x4D => { + let teams = Teams::decode(reader)?; + + Ok(Self::Teams(teams)) + } + 0x4E => { + let scoreboard_score = ScoreboardScore::decode(reader)?; + + Ok(Self::ScoreboardScore(scoreboard_score)) + } + 0x43 => { + let spawn_position = SpawnPosition::decode(reader)?; + + Ok(Self::SpawnPosition(spawn_position)) + } + 0x4F => { + let update_time = UpdateTime::decode(reader)?; + + Ok(Self::UpdateTime(update_time)) + } + 0x50 => { + let title = Title::decode(reader)?; + + Ok(Self::Title(title)) + } + 0x51 => { + let entity_sound_effect = EntitySoundEffect::decode(reader)?; + + Ok(Self::EntitySoundEffect(entity_sound_effect)) + } + 0x53 => { + let stop_sound = StopSound::decode(reader)?; + + Ok(Self::StopSound(stop_sound)) + } + 0x52 => { + let sound_effect = SoundEffect::decode(reader)?; + + Ok(Self::SoundEffect(sound_effect)) + } + 0x54 => { + let playerlist_header = PlayerlistHeader::decode(reader)?; + + Ok(Self::PlayerlistHeader(playerlist_header)) + } + 0x56 => { + let collect = Collect::decode(reader)?; + + Ok(Self::Collect(collect)) + } + 0x57 => { + let entity_teleport = EntityTeleport::decode(reader)?; + + Ok(Self::EntityTeleport(entity_teleport)) + } + 0x59 => { + let entity_update_attributes = EntityUpdateAttributes::decode(reader)?; + + Ok(Self::EntityUpdateAttributes(entity_update_attributes)) + } + 0x5A => { + let entity_effect = EntityEffect::decode(reader)?; + + Ok(Self::EntityEffect(entity_effect)) + } + 0x3D => { + let select_advancement_tab = SelectAdvancementTab::decode(reader)?; + + Ok(Self::SelectAdvancementTab(select_advancement_tab)) + } + 0x5B => Ok(Self::DeclareRecipes), + 0x5C => { + let tags = Tags::decode(reader)?; + + Ok(Self::Tags(tags)) + } + 0x08 => { + let acknowledge_player_digging = AcknowledgePlayerDigging::decode(reader)?; + + Ok(Self::AcknowledgePlayerDigging(acknowledge_player_digging)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn spawn_entity( + entity_id: i32, + object_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + pitch: i8, + yaw: i8, + object_data: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity = SpawnEntity { + entity_id, + object_uuid, + type_, + x, + y, + z, + pitch, + yaw, + object_data, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntity(spawn_entity) + } + + pub fn spawn_entity_experience_orb(entity_id: i32, x: f64, y: f64, z: f64, count: i16) -> Self { + let spawn_entity_experience_orb = SpawnEntityExperienceOrb { + entity_id, + x, + y, + z, + count, + }; + + Self::SpawnEntityExperienceOrb(spawn_entity_experience_orb) + } + + pub fn spawn_entity_weather(entity_id: i32, type_: i8, x: f64, y: f64, z: f64) -> Self { + let spawn_entity_weather = SpawnEntityWeather { + entity_id, + type_, + x, + y, + z, + }; + + Self::SpawnEntityWeather(spawn_entity_weather) + } + + pub fn spawn_entity_living( + entity_id: i32, + entity_uuid: Uuid, + type_: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + head_pitch: i8, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let spawn_entity_living = SpawnEntityLiving { + entity_id, + entity_uuid, + type_, + x, + y, + z, + yaw, + pitch, + head_pitch, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::SpawnEntityLiving(spawn_entity_living) + } + + pub fn spawn_entity_painting( + entity_id: i32, + entity_uuid: Uuid, + title: i32, + location: Position, + direction: u8, + ) -> Self { + let spawn_entity_painting = SpawnEntityPainting { + entity_id, + entity_uuid, + title, + location, + direction, + }; + + Self::SpawnEntityPainting(spawn_entity_painting) + } + + pub fn named_entity_spawn( + entity_id: i32, + player_uuid: Uuid, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + ) -> Self { + let named_entity_spawn = NamedEntitySpawn { + entity_id, + player_uuid, + x, + y, + z, + yaw, + pitch, + }; + + Self::NamedEntitySpawn(named_entity_spawn) + } + + pub fn animation(entity_id: i32, animation: u8) -> Self { + let animation = Animation { + entity_id, + animation, + }; + + Self::Animation(animation) + } + + pub fn statistics() -> Self { + Self::Statistics + } + + pub fn advancements(reset: bool) -> Self { + let advancements = Advancements { reset }; + + Self::Advancements(advancements) + } + + pub fn block_break_animation(entity_id: i32, location: Position, destroy_stage: i8) -> Self { + let block_break_animation = BlockBreakAnimation { + entity_id, + location, + destroy_stage, + }; + + Self::BlockBreakAnimation(block_break_animation) + } + + pub fn tile_entity_data(location: Position, action: u8, nbt_data: CompoundTag) -> Self { + let tile_entity_data = TileEntityData { + location, + action, + nbt_data, + }; + + Self::TileEntityData(tile_entity_data) + } + + pub fn block_action(location: Position, byte1: u8, byte2: u8, block_id: i32) -> Self { + let block_action = BlockAction { + location, + byte1, + byte2, + block_id, + }; + + Self::BlockAction(block_action) + } + + pub fn block_change(location: Position, type_: i32) -> Self { + let block_change = BlockChange { location, type_ }; + + Self::BlockChange(block_change) + } + + pub fn boss_bar(entity_uuid: Uuid, action: i32) -> Self { + let boss_bar = BossBar { + entity_uuid, + action, + }; + + Self::BossBar(boss_bar) + } + + pub fn difficulty(difficulty: u8, difficulty_locked: bool) -> Self { + let difficulty = Difficulty { + difficulty, + difficulty_locked, + }; + + Self::Difficulty(difficulty) + } + + pub fn client_bound_tab_complete(transaction_id: i32, start: i32, length: i32) -> Self { + let client_bound_tab_complete = ClientBoundTabComplete { + transaction_id, + start, + length, + }; + + Self::ClientBoundTabComplete(client_bound_tab_complete) + } + + pub fn declare_commands(root_index: i32) -> Self { + let declare_commands = DeclareCommands { root_index }; + + Self::DeclareCommands(declare_commands) + } + + pub fn face_player(feet_eyes: i32, x: f64, y: f64, z: f64, is_entity: bool) -> Self { + let face_player = FacePlayer { + feet_eyes, + x, + y, + z, + is_entity, + }; + + Self::FacePlayer(face_player) + } + + pub fn nbt_query_response(transaction_id: i32, nbt: CompoundTag) -> Self { + let nbt_query_response = NbtQueryResponse { + transaction_id, + nbt, + }; + + Self::NbtQueryResponse(nbt_query_response) + } + + pub fn client_bound_chat(message: String, position: i8) -> Self { + let client_bound_chat = ClientBoundChat { message, position }; + + Self::ClientBoundChat(client_bound_chat) + } + + pub fn multi_block_change(chunk_x: i32, chunk_z: i32) -> Self { + let multi_block_change = MultiBlockChange { chunk_x, chunk_z }; + + Self::MultiBlockChange(multi_block_change) + } + + pub fn client_bound_transaction(window_id: i8, action: i16, accepted: bool) -> Self { + let client_bound_transaction = ClientBoundTransaction { + window_id, + action, + accepted, + }; + + Self::ClientBoundTransaction(client_bound_transaction) + } + + pub fn client_bound_close_window(window_id: u8) -> Self { + let client_bound_close_window = ClientBoundCloseWindow { window_id }; + + Self::ClientBoundCloseWindow(client_bound_close_window) + } + + pub fn open_window(window_id: i32, inventory_type: i32, window_title: String) -> Self { + let open_window = OpenWindow { + window_id, + inventory_type, + window_title, + }; + + Self::OpenWindow(open_window) + } + + pub fn window_items(window_id: u8) -> Self { + let window_items = WindowItems { window_id }; + + Self::WindowItems(window_items) + } + + pub fn craft_progress_bar(window_id: u8, property: i16, value: i16) -> Self { + let craft_progress_bar = CraftProgressBar { + window_id, + property, + value, + }; + + Self::CraftProgressBar(craft_progress_bar) + } + + pub fn set_slot(window_id: i8, slot: i16, item: Option) -> Self { + let set_slot = SetSlot { + window_id, + slot, + item, + }; + + Self::SetSlot(set_slot) + } + + pub fn set_cooldown(item_id: i32, cooldown_ticks: i32) -> Self { + let set_cooldown = SetCooldown { + item_id, + cooldown_ticks, + }; + + Self::SetCooldown(set_cooldown) + } + + pub fn client_bound_custom_payload(channel: String, data: Vec) -> Self { + let client_bound_custom_payload = ClientBoundCustomPayload { channel, data }; + + Self::ClientBoundCustomPayload(client_bound_custom_payload) + } + + pub fn named_sound_effect( + sound_name: String, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let named_sound_effect = NamedSoundEffect { + sound_name, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::NamedSoundEffect(named_sound_effect) + } + + pub fn kick_disconnect(reason: String) -> Self { + let kick_disconnect = KickDisconnect { reason }; + + Self::KickDisconnect(kick_disconnect) + } + + pub fn entity_status(entity_id: i32, entity_status: i8) -> Self { + let entity_status = EntityStatus { + entity_id, + entity_status, + }; + + Self::EntityStatus(entity_status) + } + + pub fn explosion( + x: f32, + y: f32, + z: f32, + radius: f32, + player_motion_x: f32, + player_motion_y: f32, + player_motion_z: f32, + ) -> Self { + let explosion = Explosion { + x, + y, + z, + radius, + player_motion_x, + player_motion_y, + player_motion_z, + }; + + Self::Explosion(explosion) + } + + pub fn unload_chunk(chunk_x: i32, chunk_z: i32) -> Self { + let unload_chunk = UnloadChunk { chunk_x, chunk_z }; + + Self::UnloadChunk(unload_chunk) + } + + pub fn game_state_change(reason: u8, game_mode: f32) -> Self { + let game_state_change = GameStateChange { reason, game_mode }; + + Self::GameStateChange(game_state_change) + } + + pub fn open_horse_window(window_id: u8, nb_slots: i32, entity_id: i32) -> Self { + let open_horse_window = OpenHorseWindow { + window_id, + nb_slots, + entity_id, + }; + + Self::OpenHorseWindow(open_horse_window) + } + + pub fn client_bound_keep_alive(keep_alive_id: i64) -> Self { + let client_bound_keep_alive = ClientBoundKeepAlive { keep_alive_id }; + + Self::ClientBoundKeepAlive(client_bound_keep_alive) + } + + pub fn map_chunk( + x: i32, + z: i32, + ground_up: bool, + bit_map: i32, + heightmaps: CompoundTag, + chunk_data: Vec, + ) -> Self { + let map_chunk = MapChunk { + x, + z, + ground_up, + bit_map, + heightmaps, + chunk_data, + }; + + Self::MapChunk(map_chunk) + } + + pub fn world_event(effect_id: i32, location: Position, data: i32, global: bool) -> Self { + let world_event = WorldEvent { + effect_id, + location, + data, + global, + }; + + Self::WorldEvent(world_event) + } + + pub fn world_particles( + particle_id: i32, + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + particle_data: f32, + particles: i32, + data: ParticleData, + ) -> Self { + let world_particles = WorldParticles { + particle_id, + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + particle_data, + particles, + data, + }; + + Self::WorldParticles(world_particles) + } + + pub fn update_light( + chunk_x: i32, + chunk_z: i32, + sky_light_mask: i32, + block_light_mask: i32, + empty_sky_light_mask: i32, + empty_block_light_mask: i32, + data: Vec, + ) -> Self { + let update_light = UpdateLight { + chunk_x, + chunk_z, + sky_light_mask, + block_light_mask, + empty_sky_light_mask, + empty_block_light_mask, + data, + }; + + Self::UpdateLight(update_light) + } + + pub fn join_game( + entity_id: i32, + game_mode: u8, + dimension: i32, + hashed_seed: i64, + max_players: u8, + level_type: String, + view_distance: i32, + reduced_debug_info: bool, + enable_respawn_screen: bool, + ) -> Self { + let join_game = JoinGame { + entity_id, + game_mode, + dimension, + hashed_seed, + max_players, + level_type, + view_distance, + reduced_debug_info, + enable_respawn_screen, + }; + + Self::JoinGame(join_game) + } + + pub fn map( + item_damage: i32, + scale: i8, + tracking_position: bool, + locked: bool, + columns: i8, + ) -> Self { + let map = Map { + item_damage, + scale, + tracking_position, + locked, + columns, + }; + + Self::Map(map) + } + + pub fn trade_list( + window_id: i32, + villager_level: i32, + experience: i32, + is_regular_villager: bool, + can_restock: bool, + ) -> Self { + let trade_list = TradeList { + window_id, + villager_level, + experience, + is_regular_villager, + can_restock, + }; + + Self::TradeList(trade_list) + } + + pub fn rel_entity_move(entity_id: i32, d_x: i16, d_y: i16, d_z: i16, on_ground: bool) -> Self { + let rel_entity_move = RelEntityMove { + entity_id, + d_x, + d_y, + d_z, + on_ground, + }; + + Self::RelEntityMove(rel_entity_move) + } + + pub fn entity_move_look( + entity_id: i32, + d_x: i16, + d_y: i16, + d_z: i16, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_move_look = EntityMoveLook { + entity_id, + d_x, + d_y, + d_z, + yaw, + pitch, + on_ground, + }; + + Self::EntityMoveLook(entity_move_look) + } + + pub fn entity_look(entity_id: i32, yaw: i8, pitch: i8, on_ground: bool) -> Self { + let entity_look = EntityLook { + entity_id, + yaw, + pitch, + on_ground, + }; + + Self::EntityLook(entity_look) + } + + pub fn entity(entity_id: i32) -> Self { + let entity = Entity { entity_id }; + + Self::Entity(entity) + } + + pub fn client_bound_vehicle_move(x: f64, y: f64, z: f64, yaw: f32, pitch: f32) -> Self { + let client_bound_vehicle_move = ClientBoundVehicleMove { + x, + y, + z, + yaw, + pitch, + }; + + Self::ClientBoundVehicleMove(client_bound_vehicle_move) + } + + pub fn open_book(hand: i32) -> Self { + let open_book = OpenBook { hand }; + + Self::OpenBook(open_book) + } + + pub fn open_sign_entity(location: Position) -> Self { + let open_sign_entity = OpenSignEntity { location }; + + Self::OpenSignEntity(open_sign_entity) + } + + pub fn craft_recipe_response(window_id: i8, recipe: String) -> Self { + let craft_recipe_response = CraftRecipeResponse { window_id, recipe }; + + Self::CraftRecipeResponse(craft_recipe_response) + } + + pub fn client_bound_abilities(flags: i8, flying_speed: f32, walking_speed: f32) -> Self { + let client_bound_abilities = ClientBoundAbilities { + flags, + flying_speed, + walking_speed, + }; + + Self::ClientBoundAbilities(client_bound_abilities) + } + + pub fn combat_event(event: i32) -> Self { + let combat_event = CombatEvent { event }; + + Self::CombatEvent(combat_event) + } + + pub fn player_info(action: i32) -> Self { + let player_info = PlayerInfo { action }; + + Self::PlayerInfo(player_info) + } + + pub fn client_bound_position( + x: f64, + y: f64, + z: f64, + yaw: f32, + pitch: f32, + flags: i8, + teleport_id: i32, + ) -> Self { + let client_bound_position = ClientBoundPosition { + x, + y, + z, + yaw, + pitch, + flags, + teleport_id, + }; + + Self::ClientBoundPosition(client_bound_position) + } + + pub fn unlock_recipes( + action: i32, + crafting_book_open: bool, + filtering_craftable: bool, + smelting_book_open: bool, + filtering_smeltable: bool, + ) -> Self { + let unlock_recipes = UnlockRecipes { + action, + crafting_book_open, + filtering_craftable, + smelting_book_open, + filtering_smeltable, + }; + + Self::UnlockRecipes(unlock_recipes) + } + + pub fn entity_destroy() -> Self { + Self::EntityDestroy + } + + pub fn remove_entity_effect(entity_id: i32, effect_id: i8) -> Self { + let remove_entity_effect = RemoveEntityEffect { + entity_id, + effect_id, + }; + + Self::RemoveEntityEffect(remove_entity_effect) + } + + pub fn resource_pack_send(url: String, hash: String) -> Self { + let resource_pack_send = ResourcePackSend { url, hash }; + + Self::ResourcePackSend(resource_pack_send) + } + + pub fn respawn(dimension: i32, hashed_seed: i64, gamemode: u8, level_type: String) -> Self { + let respawn = Respawn { + dimension, + hashed_seed, + gamemode, + level_type, + }; + + Self::Respawn(respawn) + } + + pub fn entity_head_rotation(entity_id: i32, head_yaw: i8) -> Self { + let entity_head_rotation = EntityHeadRotation { + entity_id, + head_yaw, + }; + + Self::EntityHeadRotation(entity_head_rotation) + } + + pub fn world_border(action: i32) -> Self { + let world_border = WorldBorder { action }; + + Self::WorldBorder(world_border) + } + + pub fn camera(camera_id: i32) -> Self { + let camera = Camera { camera_id }; + + Self::Camera(camera) + } + + pub fn client_bound_held_item_slot(slot: i8) -> Self { + let client_bound_held_item_slot = ClientBoundHeldItemSlot { slot }; + + Self::ClientBoundHeldItemSlot(client_bound_held_item_slot) + } + + pub fn update_view_position(chunk_x: i32, chunk_z: i32) -> Self { + let update_view_position = UpdateViewPosition { chunk_x, chunk_z }; + + Self::UpdateViewPosition(update_view_position) + } + + pub fn update_view_distance(view_distance: i32) -> Self { + let update_view_distance = UpdateViewDistance { view_distance }; + + Self::UpdateViewDistance(update_view_distance) + } + + pub fn scoreboard_display_objective(position: i8, name: String) -> Self { + let scoreboard_display_objective = ScoreboardDisplayObjective { position, name }; + + Self::ScoreboardDisplayObjective(scoreboard_display_objective) + } + + pub fn entity_metadata(entity_id: i32, metadata: Metadata) -> Self { + let entity_metadata = EntityMetadata { + entity_id, + metadata, + }; + + Self::EntityMetadata(entity_metadata) + } + + pub fn attach_entity(entity_id: i32, vehicle_id: i32) -> Self { + let attach_entity = AttachEntity { + entity_id, + vehicle_id, + }; + + Self::AttachEntity(attach_entity) + } + + pub fn entity_velocity( + entity_id: i32, + velocity_x: i16, + velocity_y: i16, + velocity_z: i16, + ) -> Self { + let entity_velocity = EntityVelocity { + entity_id, + velocity_x, + velocity_y, + velocity_z, + }; + + Self::EntityVelocity(entity_velocity) + } + + pub fn entity_equipment(entity_id: i32, slot: i32, item: Option) -> Self { + let entity_equipment = EntityEquipment { + entity_id, + slot, + item, + }; + + Self::EntityEquipment(entity_equipment) + } + + pub fn experience(experience_bar: f32, level: i32, total_experience: i32) -> Self { + let experience = Experience { + experience_bar, + level, + total_experience, + }; + + Self::Experience(experience) + } + + pub fn update_health(health: f32, food: i32, food_saturation: f32) -> Self { + let update_health = UpdateHealth { + health, + food, + food_saturation, + }; + + Self::UpdateHealth(update_health) + } + + pub fn scoreboard_objective(name: String, action: i8) -> Self { + let scoreboard_objective = ScoreboardObjective { name, action }; + + Self::ScoreboardObjective(scoreboard_objective) + } + + pub fn set_passengers(entity_id: i32) -> Self { + let set_passengers = SetPassengers { entity_id }; + + Self::SetPassengers(set_passengers) + } + + pub fn teams(team: String, mode: i8) -> Self { + let teams = Teams { team, mode }; + + Self::Teams(teams) + } + + pub fn scoreboard_score(item_name: String, action: i8, score_name: String) -> Self { + let scoreboard_score = ScoreboardScore { + item_name, + action, + score_name, + }; + + Self::ScoreboardScore(scoreboard_score) + } + + pub fn spawn_position(location: Position) -> Self { + let spawn_position = SpawnPosition { location }; + + Self::SpawnPosition(spawn_position) + } + + pub fn update_time(age: i64, time: i64) -> Self { + let update_time = UpdateTime { age, time }; + + Self::UpdateTime(update_time) + } + + pub fn title(action: i32) -> Self { + let title = Title { action }; + + Self::Title(title) + } + + pub fn entity_sound_effect( + sound_id: i32, + sound_category: i32, + entity_id: i32, + volume: f32, + pitch: f32, + ) -> Self { + let entity_sound_effect = EntitySoundEffect { + sound_id, + sound_category, + entity_id, + volume, + pitch, + }; + + Self::EntitySoundEffect(entity_sound_effect) + } + + pub fn stop_sound(flags: i8) -> Self { + let stop_sound = StopSound { flags }; + + Self::StopSound(stop_sound) + } + + pub fn sound_effect( + sound_id: i32, + sound_category: i32, + x: i32, + y: i32, + z: i32, + volume: f32, + pitch: f32, + ) -> Self { + let sound_effect = SoundEffect { + sound_id, + sound_category, + x, + y, + z, + volume, + pitch, + }; + + Self::SoundEffect(sound_effect) + } + + pub fn playerlist_header(header: String, footer: String) -> Self { + let playerlist_header = PlayerlistHeader { header, footer }; + + Self::PlayerlistHeader(playerlist_header) + } + + pub fn collect( + collected_entity_id: i32, + collector_entity_id: i32, + pickup_item_count: i32, + ) -> Self { + let collect = Collect { + collected_entity_id, + collector_entity_id, + pickup_item_count, + }; + + Self::Collect(collect) + } + + pub fn entity_teleport( + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: i8, + pitch: i8, + on_ground: bool, + ) -> Self { + let entity_teleport = EntityTeleport { + entity_id, + x, + y, + z, + yaw, + pitch, + on_ground, + }; + + Self::EntityTeleport(entity_teleport) + } + + pub fn entity_update_attributes(entity_id: i32) -> Self { + let entity_update_attributes = EntityUpdateAttributes { entity_id }; + + Self::EntityUpdateAttributes(entity_update_attributes) + } + + pub fn entity_effect( + entity_id: i32, + effect_id: i8, + amplifier: i8, + duration: i32, + hide_particles: i8, + ) -> Self { + let entity_effect = EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + hide_particles, + }; + + Self::EntityEffect(entity_effect) + } + + pub fn select_advancement_tab(id: String) -> Self { + let select_advancement_tab = SelectAdvancementTab { id }; + + Self::SelectAdvancementTab(select_advancement_tab) + } + + pub fn declare_recipes() -> Self { + Self::DeclareRecipes + } + + pub fn tags( + block_tags: TagsMap, + item_tags: TagsMap, + fluid_tags: TagsMap, + entity_tags: TagsMap, + ) -> Self { + let tags = Tags { + block_tags, + item_tags, + fluid_tags, + entity_tags, + }; + + Self::Tags(tags) + } + + pub fn acknowledge_player_digging( + location: Position, + block: i32, + status: i32, + successful: bool, + ) -> Self { + let acknowledge_player_digging = AcknowledgePlayerDigging { + location, + block, + status, + successful, + }; + + Self::AcknowledgePlayerDigging(acknowledge_player_digging) + } +} + +#[derive(Packet, Debug)] +pub struct TeleportConfirm { + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryBlockNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct SetDifficulty { + pub new_difficulty: u8, +} + +#[derive(Packet, Debug)] +pub struct EditBook { + pub new_book: Option, + pub signing: bool, + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct QueryEntityNbt { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct PickItem { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct NameItem { + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct SelectTrade { + #[packet(with = "var_int")] + pub slot: i32, +} + +#[derive(Packet, Debug)] +pub struct SetBeaconEffect { + #[packet(with = "var_int")] + pub primary_effect: i32, + #[packet(with = "var_int")] + pub secondary_effect: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlock { + pub location: Position, + pub command: String, + #[packet(with = "var_int")] + pub mode: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct UpdateCommandBlockMinecart { + #[packet(with = "var_int")] + pub entity_id: i32, + pub command: String, + pub track_output: bool, +} + +#[derive(Packet, Debug)] +pub struct UpdateStructureBlock { + pub location: Position, + #[packet(with = "var_int")] + pub action: i32, + #[packet(with = "var_int")] + pub mode: i32, + pub name: String, + pub offset_x: u8, + pub offset_y: u8, + pub offset_z: u8, + pub size_x: u8, + pub size_y: u8, + pub size_z: u8, + #[packet(with = "var_int")] + pub mirror: i32, + #[packet(with = "var_int")] + pub rotation: i32, + pub metadata: String, + pub integrity: f32, + #[packet(with = "var_int")] + pub seed: i32, + pub flags: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub text: String, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundChat { + pub message: String, +} + +#[derive(Packet, Debug)] +pub struct ClientCommand { + #[packet(with = "var_int")] + pub action_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Settings { + pub locale: String, + pub view_distance: i8, + #[packet(with = "var_int")] + pub chat_flags: i32, + pub chat_colors: bool, + pub skin_parts: u8, + #[packet(with = "var_int")] + pub main_hand: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct EnchantItem { + pub window_id: i8, + pub enchantment: i8, +} + +#[derive(Packet, Debug)] +pub struct WindowClick { + pub window_id: u8, + pub slot: i16, + pub mouse_button: i8, + pub action: i16, + pub mode: i8, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct UseEntity { + #[packet(with = "var_int")] + pub target: i32, + #[packet(with = "var_int")] + pub mouse: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct LockDifficulty { + pub locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct PositionLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Look { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Flying { + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct SteerBoat { + pub left_paddle: bool, + pub right_paddle: bool, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeRequest { + pub window_id: i8, + pub recipe: String, + pub make_all: bool, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct BlockDig { + pub status: i8, + pub location: Position, + pub face: i8, +} + +#[derive(Packet, Debug)] +pub struct EntityAction { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub action_id: i32, + #[packet(with = "var_int")] + pub jump_boost: i32, +} + +#[derive(Packet, Debug)] +pub struct SteerVehicle { + pub sideways: f32, + pub forward: f32, + pub jump: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftingBookData { + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackReceive { + #[packet(with = "var_int")] + pub result: i32, +} + +#[derive(Packet, Debug)] +pub struct ServerBoundHeldItemSlot { + pub slot_id: i16, +} + +#[derive(Packet, Debug)] +pub struct SetCreativeSlot { + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct UpdateJigsawBlock { + pub location: Position, + pub name: String, + pub target: String, + pub pool: String, + pub final_state: String, + pub joint_type: String, +} + +#[derive(Packet, Debug)] +pub struct UpdateSign { + pub location: Position, + pub text1: String, + pub text2: String, + pub text3: String, + pub text4: String, +} + +#[derive(Packet, Debug)] +pub struct ArmAnimation { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct Spectate { + pub target: Uuid, +} + +#[derive(Packet, Debug)] +pub struct BlockPlace { + #[packet(with = "var_int")] + pub hand: i32, + pub location: Position, + #[packet(with = "var_int")] + pub direction: i32, + pub cursor_x: f32, + pub cursor_y: f32, + pub cursor_z: f32, + pub inside_block: bool, +} + +#[derive(Packet, Debug)] +pub struct UseItem { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct AdvancementTab { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub object_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub pitch: i8, + pub yaw: i8, + pub object_data: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityExperienceOrb { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub count: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityWeather { + #[packet(with = "var_int")] + pub entity_id: i32, + pub type_: i8, + pub x: f64, + pub y: f64, + pub z: f64, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityLiving { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub type_: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub head_pitch: i8, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct SpawnEntityPainting { + #[packet(with = "var_int")] + pub entity_id: i32, + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub title: i32, + pub location: Position, + pub direction: u8, +} + +#[derive(Packet, Debug)] +pub struct NamedEntitySpawn { + #[packet(with = "var_int")] + pub entity_id: i32, + pub player_uuid: Uuid, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, +} + +#[derive(Packet, Debug)] +pub struct Animation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub animation: u8, +} + +#[derive(Packet, Debug)] +pub struct Advancements { + pub reset: bool, +} + +#[derive(Packet, Debug)] +pub struct BlockBreakAnimation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub location: Position, + pub destroy_stage: i8, +} + +#[derive(Packet, Debug)] +pub struct TileEntityData { + pub location: Position, + pub action: u8, + pub nbt_data: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct BlockAction { + pub location: Position, + pub byte1: u8, + pub byte2: u8, + #[packet(with = "var_int")] + pub block_id: i32, +} + +#[derive(Packet, Debug)] +pub struct BlockChange { + pub location: Position, + #[packet(with = "var_int")] + pub type_: i32, +} + +#[derive(Packet, Debug)] +pub struct BossBar { + pub entity_uuid: Uuid, + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Difficulty { + pub difficulty: u8, + pub difficulty_locked: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTabComplete { + #[packet(with = "var_int")] + pub transaction_id: i32, + #[packet(with = "var_int")] + pub start: i32, + #[packet(with = "var_int")] + pub length: i32, +} + +#[derive(Packet, Debug)] +pub struct DeclareCommands { + #[packet(with = "var_int")] + pub root_index: i32, +} + +#[derive(Packet, Debug)] +pub struct FacePlayer { + #[packet(with = "var_int")] + pub feet_eyes: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub is_entity: bool, +} + +#[derive(Packet, Debug)] +pub struct NbtQueryResponse { + #[packet(with = "var_int")] + pub transaction_id: i32, + pub nbt: CompoundTag, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundChat { + pub message: String, + pub position: i8, +} + +#[derive(Packet, Debug)] +pub struct MultiBlockChange { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundTransaction { + pub window_id: i8, + pub action: i16, + pub accepted: bool, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCloseWindow { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct OpenWindow { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub inventory_type: i32, + pub window_title: String, +} + +#[derive(Packet, Debug)] +pub struct WindowItems { + pub window_id: u8, +} + +#[derive(Packet, Debug)] +pub struct CraftProgressBar { + pub window_id: u8, + pub property: i16, + pub value: i16, +} + +#[derive(Packet, Debug)] +pub struct SetSlot { + pub window_id: i8, + pub slot: i16, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct SetCooldown { + #[packet(with = "var_int")] + pub item_id: i32, + #[packet(with = "var_int")] + pub cooldown_ticks: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundCustomPayload { + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct NamedSoundEffect { + pub sound_name: String, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct KickDisconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EntityStatus { + pub entity_id: i32, + pub entity_status: i8, +} + +#[derive(Packet, Debug)] +pub struct Explosion { + pub x: f32, + pub y: f32, + pub z: f32, + pub radius: f32, + pub player_motion_x: f32, + pub player_motion_y: f32, + pub player_motion_z: f32, +} + +#[derive(Packet, Debug)] +pub struct UnloadChunk { + pub chunk_x: i32, + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct GameStateChange { + pub reason: u8, + pub game_mode: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenHorseWindow { + pub window_id: u8, + #[packet(with = "var_int")] + pub nb_slots: i32, + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundKeepAlive { + pub keep_alive_id: i64, +} + +#[derive(Packet, Debug)] +pub struct MapChunk { + pub x: i32, + pub z: i32, + pub ground_up: bool, + #[packet(with = "var_int")] + pub bit_map: i32, + pub heightmaps: CompoundTag, + pub chunk_data: Vec, +} + +#[derive(Packet, Debug)] +pub struct WorldEvent { + pub effect_id: i32, + pub location: Position, + pub data: i32, + pub global: bool, +} + +#[derive(Packet, Debug)] +pub struct WorldParticles { + pub particle_id: i32, + pub long_distance: bool, + pub x: f64, + pub y: f64, + pub z: f64, + pub offset_x: f32, + pub offset_y: f32, + pub offset_z: f32, + pub particle_data: f32, + pub particles: i32, + pub data: ParticleData, +} + +#[derive(Packet, Debug)] +pub struct UpdateLight { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, + #[packet(with = "var_int")] + pub sky_light_mask: i32, + #[packet(with = "var_int")] + pub block_light_mask: i32, + #[packet(with = "var_int")] + pub empty_sky_light_mask: i32, + #[packet(with = "var_int")] + pub empty_block_light_mask: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct JoinGame { + pub entity_id: i32, + pub game_mode: u8, + pub dimension: i32, + pub hashed_seed: i64, + pub max_players: u8, + pub level_type: String, + #[packet(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, +} + +#[derive(Packet, Debug)] +pub struct Map { + #[packet(with = "var_int")] + pub item_damage: i32, + pub scale: i8, + pub tracking_position: bool, + pub locked: bool, + pub columns: i8, +} + +#[derive(Packet, Debug)] +pub struct TradeList { + #[packet(with = "var_int")] + pub window_id: i32, + #[packet(with = "var_int")] + pub villager_level: i32, + #[packet(with = "var_int")] + pub experience: i32, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Packet, Debug)] +pub struct RelEntityMove { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityMoveLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub d_x: i16, + pub d_y: i16, + pub d_z: i16, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityLook { + #[packet(with = "var_int")] + pub entity_id: i32, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct Entity { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundVehicleMove { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct OpenBook { + #[packet(with = "var_int")] + pub hand: i32, +} + +#[derive(Packet, Debug)] +pub struct OpenSignEntity { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct CraftRecipeResponse { + pub window_id: i8, + pub recipe: String, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundAbilities { + pub flags: i8, + pub flying_speed: f32, + pub walking_speed: f32, +} + +#[derive(Packet, Debug)] +pub struct CombatEvent { + #[packet(with = "var_int")] + pub event: i32, +} + +#[derive(Packet, Debug)] +pub struct PlayerInfo { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundPosition { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: i8, + #[packet(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Packet, Debug)] +pub struct UnlockRecipes { + #[packet(with = "var_int")] + pub action: i32, + pub crafting_book_open: bool, + pub filtering_craftable: bool, + pub smelting_book_open: bool, + pub filtering_smeltable: bool, +} + +#[derive(Packet, Debug)] +pub struct RemoveEntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, +} + +#[derive(Packet, Debug)] +pub struct ResourcePackSend { + pub url: String, + pub hash: String, +} + +#[derive(Packet, Debug)] +pub struct Respawn { + pub dimension: i32, + pub hashed_seed: i64, + pub gamemode: u8, + pub level_type: String, +} + +#[derive(Packet, Debug)] +pub struct EntityHeadRotation { + #[packet(with = "var_int")] + pub entity_id: i32, + pub head_yaw: i8, +} + +#[derive(Packet, Debug)] +pub struct WorldBorder { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct Camera { + #[packet(with = "var_int")] + pub camera_id: i32, +} + +#[derive(Packet, Debug)] +pub struct ClientBoundHeldItemSlot { + pub slot: i8, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewPosition { + #[packet(with = "var_int")] + pub chunk_x: i32, + #[packet(with = "var_int")] + pub chunk_z: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateViewDistance { + #[packet(with = "var_int")] + pub view_distance: i32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardDisplayObjective { + pub position: i8, + pub name: String, +} + +#[derive(Packet, Debug)] +pub struct EntityMetadata { + #[packet(with = "var_int")] + pub entity_id: i32, + pub metadata: Metadata, +} + +#[derive(Packet, Debug)] +pub struct AttachEntity { + pub entity_id: i32, + pub vehicle_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityVelocity { + #[packet(with = "var_int")] + pub entity_id: i32, + pub velocity_x: i16, + pub velocity_y: i16, + pub velocity_z: i16, +} + +#[derive(Packet, Debug)] +pub struct EntityEquipment { + #[packet(with = "var_int")] + pub entity_id: i32, + #[packet(with = "var_int")] + pub slot: i32, + pub item: Option, +} + +#[derive(Packet, Debug)] +pub struct Experience { + pub experience_bar: f32, + #[packet(with = "var_int")] + pub level: i32, + #[packet(with = "var_int")] + pub total_experience: i32, +} + +#[derive(Packet, Debug)] +pub struct UpdateHealth { + pub health: f32, + #[packet(with = "var_int")] + pub food: i32, + pub food_saturation: f32, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardObjective { + pub name: String, + pub action: i8, +} + +#[derive(Packet, Debug)] +pub struct SetPassengers { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct Teams { + pub team: String, + pub mode: i8, +} + +#[derive(Packet, Debug)] +pub struct ScoreboardScore { + pub item_name: String, + pub action: i8, + pub score_name: String, +} + +#[derive(Packet, Debug)] +pub struct SpawnPosition { + pub location: Position, +} + +#[derive(Packet, Debug)] +pub struct UpdateTime { + pub age: i64, + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct Title { + #[packet(with = "var_int")] + pub action: i32, +} + +#[derive(Packet, Debug)] +pub struct EntitySoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + #[packet(with = "var_int")] + pub entity_id: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct StopSound { + pub flags: i8, +} + +#[derive(Packet, Debug)] +pub struct SoundEffect { + #[packet(with = "var_int")] + pub sound_id: i32, + #[packet(with = "var_int")] + pub sound_category: i32, + pub x: i32, + pub y: i32, + pub z: i32, + pub volume: f32, + pub pitch: f32, +} + +#[derive(Packet, Debug)] +pub struct PlayerlistHeader { + pub header: String, + pub footer: String, +} + +#[derive(Packet, Debug)] +pub struct Collect { + #[packet(with = "var_int")] + pub collected_entity_id: i32, + #[packet(with = "var_int")] + pub collector_entity_id: i32, + #[packet(with = "var_int")] + pub pickup_item_count: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityTeleport { + #[packet(with = "var_int")] + pub entity_id: i32, + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: i8, + pub pitch: i8, + pub on_ground: bool, +} + +#[derive(Packet, Debug)] +pub struct EntityUpdateAttributes { + #[packet(with = "var_int")] + pub entity_id: i32, +} + +#[derive(Packet, Debug)] +pub struct EntityEffect { + #[packet(with = "var_int")] + pub entity_id: i32, + pub effect_id: i8, + pub amplifier: i8, + #[packet(with = "var_int")] + pub duration: i32, + pub hide_particles: i8, +} + +#[derive(Packet, Debug)] +pub struct SelectAdvancementTab { + pub id: String, +} + +#[derive(Packet, Debug)] +pub struct Tags { + pub block_tags: TagsMap, + pub item_tags: TagsMap, + pub fluid_tags: TagsMap, + pub entity_tags: TagsMap, +} + +#[derive(Packet, Debug)] +pub struct AcknowledgePlayerDigging { + pub location: Position, + #[packet(with = "var_int")] + pub block: i32, + #[packet(with = "var_int")] + pub status: i32, + pub successful: bool, +} diff --git a/protocol/src/version/v_20w13b/handshake.rs b/protocol/src/version/v_20w13b/handshake.rs new file mode 100644 index 0000000..0ca7960 --- /dev/null +++ b/protocol/src/version/v_20w13b/handshake.rs @@ -0,0 +1,55 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundHandshakePacket { + SetProtocol(SetProtocol), +} + +impl ServerBoundHandshakePacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::SetProtocol(_) => 0x00, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let set_protocol = SetProtocol::decode(reader)?; + + Ok(Self::SetProtocol(set_protocol)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn set_protocol( + protocol_version: i32, + server_host: String, + server_port: u16, + next_state: i32, + ) -> Self { + let set_protocol = SetProtocol { + protocol_version, + server_host, + server_port, + next_state, + }; + + Self::SetProtocol(set_protocol) + } +} + +#[derive(Packet, Debug)] +pub struct SetProtocol { + #[packet(with = "var_int")] + pub protocol_version: i32, + pub server_host: String, + pub server_port: u16, + #[packet(with = "var_int")] + pub next_state: i32, +} diff --git a/protocol/src/version/v_20w13b/login.rs b/protocol/src/version/v_20w13b/login.rs new file mode 100644 index 0000000..d29fe54 --- /dev/null +++ b/protocol/src/version/v_20w13b/login.rs @@ -0,0 +1,211 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +use uuid::Uuid; + +pub enum ServerBoundLoginPacket { + LoginStart(LoginStart), + EncryptionResponse(EncryptionResponse), + LoginPluginResponse(LoginPluginResponse), +} + +impl ServerBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::LoginStart(_) => 0x00, + Self::EncryptionResponse(_) => 0x01, + Self::LoginPluginResponse(_) => 0x02, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let login_start = LoginStart::decode(reader)?; + + Ok(Self::LoginStart(login_start)) + } + 0x01 => { + let encryption_response = EncryptionResponse::decode(reader)?; + + Ok(Self::EncryptionResponse(encryption_response)) + } + 0x02 => { + let login_plugin_response = LoginPluginResponse::decode(reader)?; + + Ok(Self::LoginPluginResponse(login_plugin_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn login_start(username: String) -> Self { + let login_start = LoginStart { username }; + + Self::LoginStart(login_start) + } + + pub fn encryption_response(shared_secret: Vec, verify_token: Vec) -> Self { + let encryption_response = EncryptionResponse { + shared_secret, + verify_token, + }; + + Self::EncryptionResponse(encryption_response) + } + + pub fn login_plugin_response(message_id: i32, data: Vec) -> Self { + let login_plugin_response = LoginPluginResponse { message_id, data }; + + Self::LoginPluginResponse(login_plugin_response) + } +} + +pub enum ClientBoundLoginPacket { + Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + Success(Success), + Compress(Compress), + LoginPluginRequest(LoginPluginRequest), +} + +impl ClientBoundLoginPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::Disconnect(_) => 0x00, + Self::EncryptionRequest(_) => 0x01, + Self::Success(_) => 0x02, + Self::Compress(_) => 0x03, + Self::LoginPluginRequest(_) => 0x04, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let disconnect = Disconnect::decode(reader)?; + + Ok(Self::Disconnect(disconnect)) + } + 0x01 => { + let encryption_request = EncryptionRequest::decode(reader)?; + + Ok(Self::EncryptionRequest(encryption_request)) + } + 0x02 => { + let success = Success::decode(reader)?; + + Ok(Self::Success(success)) + } + 0x03 => { + let compress = Compress::decode(reader)?; + + Ok(Self::Compress(compress)) + } + 0x04 => { + let login_plugin_request = LoginPluginRequest::decode(reader)?; + + Ok(Self::LoginPluginRequest(login_plugin_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn disconnect(reason: String) -> Self { + let disconnect = Disconnect { reason }; + + Self::Disconnect(disconnect) + } + + pub fn encryption_request( + server_id: String, + public_key: Vec, + verify_token: Vec, + ) -> Self { + let encryption_request = EncryptionRequest { + server_id, + public_key, + verify_token, + }; + + Self::EncryptionRequest(encryption_request) + } + + pub fn success(uuid: Uuid, username: String) -> Self { + let success = Success { uuid, username }; + + Self::Success(success) + } + + pub fn compress(threshold: i32) -> Self { + let compress = Compress { threshold }; + + Self::Compress(compress) + } + + pub fn login_plugin_request(message_id: i32, channel: String, data: Vec) -> Self { + let login_plugin_request = LoginPluginRequest { + message_id, + channel, + data, + }; + + Self::LoginPluginRequest(login_plugin_request) + } +} + +#[derive(Packet, Debug)] +pub struct LoginStart { + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionResponse { + pub shared_secret: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginResponse { + #[packet(with = "var_int")] + pub message_id: i32, + #[packet(with = "rest")] + pub data: Vec, +} + +#[derive(Packet, Debug)] +pub struct Disconnect { + pub reason: String, +} + +#[derive(Packet, Debug)] +pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, +} + +#[derive(Packet, Debug)] +pub struct Success { + pub uuid: Uuid, + pub username: String, +} + +#[derive(Packet, Debug)] +pub struct Compress { + #[packet(with = "var_int")] + pub threshold: i32, +} + +#[derive(Packet, Debug)] +pub struct LoginPluginRequest { + #[packet(with = "var_int")] + pub message_id: i32, + pub channel: String, + #[packet(with = "rest")] + pub data: Vec, +} diff --git a/protocol/src/version/v_20w13b/mod.rs b/protocol/src/version/v_20w13b/mod.rs new file mode 100644 index 0000000..be1079b --- /dev/null +++ b/protocol/src/version/v_20w13b/mod.rs @@ -0,0 +1,6 @@ +// This file is automatically generated. +// It is not intended for manual editing. +pub mod game; +pub mod handshake; +pub mod login; +pub mod status; diff --git a/protocol/src/version/v_20w13b/status.rs b/protocol/src/version/v_20w13b/status.rs new file mode 100644 index 0000000..20fb7b7 --- /dev/null +++ b/protocol/src/version/v_20w13b/status.rs @@ -0,0 +1,99 @@ +// This file is automatically generated. +// It is not intended for manual editing. +use crate::DecodeError; +use crate::Decoder; +use minecraft_protocol_derive::Packet; +use std::io::Read; + +pub enum ServerBoundStatusPacket { + StatusRequest, + PingRequest(PingRequest), +} + +impl ServerBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusRequest => 0x00, + Self::PingRequest(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => Ok(Self::StatusRequest), + 0x01 => { + let ping_request = PingRequest::decode(reader)?; + + Ok(Self::PingRequest(ping_request)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_request() -> Self { + Self::StatusRequest + } + + pub fn ping_request(time: i64) -> Self { + let ping_request = PingRequest { time }; + + Self::PingRequest(ping_request) + } +} + +pub enum ClientBoundStatusPacket { + StatusResponse(StatusResponse), + PingResponse(PingResponse), +} + +impl ClientBoundStatusPacket { + pub fn get_type_id(&self) -> u8 { + match self { + Self::StatusResponse(_) => 0x00, + Self::PingResponse(_) => 0x01, + } + } + + pub fn decode(type_id: u8, reader: &mut R) -> Result { + match type_id { + 0x00 => { + let status_response = StatusResponse::decode(reader)?; + + Ok(Self::StatusResponse(status_response)) + } + 0x01 => { + let ping_response = PingResponse::decode(reader)?; + + Ok(Self::PingResponse(ping_response)) + } + _ => Err(DecodeError::UnknownPacketType { type_id }), + } + } + + pub fn status_response(response: String) -> Self { + let status_response = StatusResponse { response }; + + Self::StatusResponse(status_response) + } + + pub fn ping_response(time: i64) -> Self { + let ping_response = PingResponse { time }; + + Self::PingResponse(ping_response) + } +} + +#[derive(Packet, Debug)] +pub struct PingRequest { + pub time: i64, +} + +#[derive(Packet, Debug)] +pub struct StatusResponse { + pub response: String, +} + +#[derive(Packet, Debug)] +pub struct PingResponse { + pub time: i64, +}