From 0a0835fd2d3ee674aa2a84bff9cb8274510dc004 Mon Sep 17 00:00:00 2001
From: Vladislavs Golubs <vladislavs.golubs@yandex.ru>
Date: Sun, 7 Feb 2021 18:40:11 +0300
Subject: [PATCH] Add game packets

---
 .travis.yml                           |   24 -
 protocol-generator/src/data/output.rs |    3 +-
 protocol-generator/src/main.rs        |   73 +-
 protocol/src/packet/game.rs           | 3421 ++++++++++++++++++++++++-
 protocol/src/packet/login.rs          |   70 +-
 5 files changed, 3458 insertions(+), 133 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<output::Packet> {
@@ -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<output::DataType> {
     }
 }
 
-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),
-}
-
-pub enum GameClientBoundPacket {
-    ClientBoundChatMessage(ClientBoundChatMessage),
-    JoinGame(JoinGame),
-    ClientBoundKeepAlive(ClientBoundKeepAlive),
-    ChunkData(ChunkData),
-    GameDisconnect(GameDisconnect),
+    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 {
-            GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03,
-            GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F,
+            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<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
         match type_id {
-            0x03 => {
-                let chat_message = ServerBoundChatMessage::decode(reader)?;
+            0x00 => {
+                let teleport_confirm = TeleportConfirm::decode(reader)?;
 
-                Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message))
+                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 keep_alive = ServerBoundKeepAlive::decode(reader)?;
+                let server_bound_keep_alive = ServerBoundKeepAlive::decode(reader)?;
 
-                Ok(GameServerBoundPacket::ServerBoundKeepAlive(keep_alive))
+                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<u8>) -> 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 {
+    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),
+    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 {
-            GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
-            GameClientBoundPacket::GameDisconnect(_) => 0x1A,
-            GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20,
-            GameClientBoundPacket::ChunkData(_) => 0x21,
-            GameClientBoundPacket::JoinGame(_) => 0x25,
+            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<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
         match type_id {
-            0x0E => {
-                let chat_message = ClientBoundChatMessage::decode(reader)?;
+            0x00 => {
+                let spawn_entity = SpawnEntity::decode(reader)?;
 
-                Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message))
+                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 game_disconnect = GameDisconnect::decode(reader)?;
+                let kick_disconnect = KickDisconnect::decode(reader)?;
 
-                Ok(GameClientBoundPacket::GameDisconnect(game_disconnect))
+                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 keep_alive = ClientBoundKeepAlive::decode(reader)?;
+                let client_bound_keep_alive = ClientBoundKeepAlive::decode(reader)?;
 
-                Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive))
+                Ok(Self::ClientBoundKeepAlive(client_bound_keep_alive))
             }
             0x21 => {
-                let chunk_data = ChunkData::decode(reader)?;
+                let map_chunk = MapChunk::decode(reader)?;
 
-                Ok(GameClientBoundPacket::ChunkData(chunk_data))
+                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)?;
+                let login = Login::decode(reader)?;
 
-                Ok(GameClientBoundPacket::JoinGame(join_game))
+                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<u8>) -> 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<u8>,
+    ) -> 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<u8>,
+    ) -> 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 ServerBoundChatMessage {
-    #[packet(max_length = 256)]
+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 ClientBoundChatMessage {
-    pub message: Message,
-    pub position: MessagePosition,
+pub struct ClientCommand {
+    #[packet(with = "var_int")]
+    pub action_id: i32,
 }
 
 #[derive(Packet, Debug)]
-pub struct JoinGame {
-    pub entity_id: u32,
-    pub game_mode: GameMode,
+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<u8>,
+}
+
+#[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,
+}
+
+#[derive(Packet, Debug)]
+pub struct SetSlot {
+    pub window_id: i8,
+    pub slot: i16,
+}
+
+#[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<u8>,
+}
+
+#[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<u8>,
+}
+
+#[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 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<u8>,
+}
+
+#[derive(Packet, Debug)]
+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)]
-pub struct ClientBoundKeepAlive {
-    pub id: u64,
-}
-
 #[derive(Packet, Debug)]
-pub struct ChunkData {
-    pub x: i32,
-    pub z: i32,
-    pub full: bool,
+pub struct Map {
     #[packet(with = "var_int")]
-    pub primary_mask: i32,
-    pub heights: CompoundTag,
-    pub data: Vec<u8>,
-    pub tiles: Vec<CompoundTag>,
+    pub item_damage: i32,
+    pub scale: i8,
+    pub tracking_position: bool,
+    pub locked: bool,
+    pub columns: i8,
 }
 
 #[derive(Packet, Debug)]
-pub struct GameDisconnect {
-    pub reason: Message,
+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 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 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<u8>, verify_token: Vec<u8>) -> 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<u8>) -> 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<u8>,
-        verify_token: Vec<u8>,
-    ) -> Self {
+    pub fn encryption_request(server_id: String, public_key: Vec<u8>, verify_token: Vec<u8>) -> 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<u8>,
-    pub verify_token: Vec<u8>,
+    pub verify_token: Vec<u8>
 }
 
 #[derive(Packet, Debug)]
@@ -174,32 +182,33 @@ pub struct LoginPluginResponse {
     #[packet(with = "var_int")]
     pub message_id: i32,
     #[packet(with = "rest")]
-    pub data: Vec<u8>,
+    pub data: Vec<u8>
 }
 
+
 #[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<u8>,
-    pub verify_token: Vec<u8>,
+    pub verify_token: Vec<u8>
 }
 
 #[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<u8>,
+    pub data: Vec<u8>
 }
+