diff --git a/extractor/src/main/kotlin/de/snowii/extractor/Extractor.kt b/extractor/src/main/kotlin/de/snowii/extractor/Extractor.kt index dfedee0c3..a9ff4007d 100644 --- a/extractor/src/main/kotlin/de/snowii/extractor/Extractor.kt +++ b/extractor/src/main/kotlin/de/snowii/extractor/Extractor.kt @@ -28,7 +28,7 @@ class Extractor : ModInitializer { Particles(), SyncedRegistries(), Packet(), - Screen(), + Screens(), Items(), Blocks(), ) diff --git a/extractor/src/main/kotlin/de/snowii/extractor/extractors/Recipes.kt b/extractor/src/main/kotlin/de/snowii/extractor/extractors/Recipes.kt index bc58511ae..de6243cce 100644 --- a/extractor/src/main/kotlin/de/snowii/extractor/extractors/Recipes.kt +++ b/extractor/src/main/kotlin/de/snowii/extractor/extractors/Recipes.kt @@ -46,7 +46,6 @@ class Recipes : Extractor.Extractor { } } recipeJson.add("ingredients", ingredientArray) -// recipeJson.addProperty("placementSlots", gson.toJson(recipe.ingredientPlacement.placementSlots)) recipesJson.add(recipeJson) } diff --git a/extractor/src/main/kotlin/de/snowii/extractor/extractors/Screen.kt b/extractor/src/main/kotlin/de/snowii/extractor/extractors/Screens.kt similarity index 95% rename from extractor/src/main/kotlin/de/snowii/extractor/extractors/Screen.kt rename to extractor/src/main/kotlin/de/snowii/extractor/extractors/Screens.kt index 54ad23418..42b8a165f 100644 --- a/extractor/src/main/kotlin/de/snowii/extractor/extractors/Screen.kt +++ b/extractor/src/main/kotlin/de/snowii/extractor/extractors/Screens.kt @@ -7,7 +7,7 @@ import de.snowii.extractor.Extractor import net.minecraft.registry.Registries import net.minecraft.server.MinecraftServer -class Screen : Extractor.Extractor { +class Screens : Extractor.Extractor { override fun fileName(): String { return "screens.json" } diff --git a/pumpkin-macros/src/lib.rs b/pumpkin-macros/src/lib.rs index 989641c9c..cd7c79580 100644 --- a/pumpkin-macros/src/lib.rs +++ b/pumpkin-macros/src/lib.rs @@ -17,7 +17,28 @@ pub fn client_packet(input: TokenStream, item: TokenStream) -> TokenStream { let gen = quote! { #item - impl #impl_generics crate::bytebuf::packet_id::ClientPacketID for #name #ty_generics { + impl #impl_generics crate::bytebuf::packet_id::Packet for #name #ty_generics { + const PACKET_ID: i32 = #input as i32; + } + }; + + gen.into() +} + +#[proc_macro_attribute] +pub fn server_packet(input: TokenStream, item: TokenStream) -> TokenStream { + let ast: syn::DeriveInput = syn::parse(item.clone()).unwrap(); + + let name = &ast.ident; + + let (impl_generics, ty_generics, _) = ast.generics.split_for_impl(); + + let input: proc_macro2::TokenStream = packet::packet_serverbound(input); + let item: proc_macro2::TokenStream = item.into(); + + let gen = quote! { + #item + impl #impl_generics crate::bytebuf::packet_id::Packet for #name #ty_generics { const PACKET_ID: i32 = #input as i32; } }; diff --git a/pumpkin-macros/src/packet.rs b/pumpkin-macros/src/packet.rs index 2b0b838e3..0d0a7c1a7 100644 --- a/pumpkin-macros/src/packet.rs +++ b/pumpkin-macros/src/packet.rs @@ -30,7 +30,6 @@ pub(crate) fn packet_clientbound(item: TokenStream) -> proc_macro2::TokenStream quote! { #id } } -#[expect(dead_code)] pub(crate) fn packet_serverbound(item: TokenStream) -> proc_macro2::TokenStream { let input_string = item.to_string(); let packet_name = input_string.trim_matches('"'); diff --git a/pumpkin-protocol/src/bytebuf/packet_id.rs b/pumpkin-protocol/src/bytebuf/packet_id.rs index c8d17c695..f2505b832 100644 --- a/pumpkin-protocol/src/bytebuf/packet_id.rs +++ b/pumpkin-protocol/src/bytebuf/packet_id.rs @@ -130,13 +130,13 @@ impl<'de> Deserialize<'de> for VarLong { } } -pub trait ClientPacketID { +pub trait Packet { const PACKET_ID: VarIntType; } impl

ClientPacket for P where - P: ClientPacketID + Serialize, + P: Packet + Serialize, { fn write(&self, bytebuf: &mut ByteBuffer) { let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); @@ -151,7 +151,7 @@ where impl

ServerPacket for P where - P: DeserializeOwned, + P: Packet + DeserializeOwned, { fn read(bytebuf: &mut ByteBuffer) -> Result { let deserializer = deserializer::Deserializer::new(bytebuf); diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 5def3df30..b550ff43e 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -1,4 +1,4 @@ -use bytebuf::{packet_id::ClientPacketID, ByteBuffer, DeserializerError}; +use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError}; use pumpkin_core::text::{style::Style, TextComponent}; use serde::{Deserialize, Serialize}; @@ -72,11 +72,11 @@ pub struct RawPacket { pub bytebuf: ByteBuffer, } -pub trait ClientPacket: ClientPacketID { +pub trait ClientPacket: Packet { fn write(&self, bytebuf: &mut ByteBuffer); } -pub trait ServerPacket: Sized { +pub trait ServerPacket: Packet + Sized { fn read(bytebuf: &mut ByteBuffer) -> Result; } diff --git a/pumpkin-protocol/src/server/config/mod.rs b/pumpkin-protocol/src/server/config/mod.rs index b59b0e705..164c8e60a 100644 --- a/pumpkin-protocol/src/server/config/mod.rs +++ b/pumpkin-protocol/src/server/config/mod.rs @@ -3,22 +3,7 @@ mod s_client_information; mod s_known_packs; mod s_plugin_message; -use num_derive::FromPrimitive; pub use s_acknowledge_finish_config::*; pub use s_client_information::*; pub use s_known_packs::*; pub use s_plugin_message::*; - -/// DO NOT CHANGE ORDER -/// This Enum has the exact order like vanilla, Vanilla parses their Packet IDs from the enum order. Its also way easier to port. -#[derive(FromPrimitive)] -pub enum ServerboundConfigPackets { - ClientInformation, - CookieResponse, - PluginMessage, - AcknowledgedFinish, - KeepAlive, - Pong, - ResourcePackResponse, - KnownPacks, -} diff --git a/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs b/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs index 20b81d462..7796b8510 100644 --- a/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs +++ b/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs @@ -1,2 +1,5 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("configuration:finish_configuration")] pub struct SAcknowledgeFinishConfig {} diff --git a/pumpkin-protocol/src/server/config/s_client_information.rs b/pumpkin-protocol/src/server/config/s_client_information.rs index 4ec1a6984..ba6823f7e 100644 --- a/pumpkin-protocol/src/server/config/s_client_information.rs +++ b/pumpkin-protocol/src/server/config/s_client_information.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("configuration:client_information")] pub struct SClientInformationConfig { pub locale: String, // 16 pub view_distance: i8, diff --git a/pumpkin-protocol/src/server/config/s_known_packs.rs b/pumpkin-protocol/src/server/config/s_known_packs.rs index f468609cd..138cf2ae2 100644 --- a/pumpkin-protocol/src/server/config/s_known_packs.rs +++ b/pumpkin-protocol/src/server/config/s_known_packs.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("configuration:select_known_packs")] pub struct SKnownPacks { pub known_pack_count: VarInt, // known_packs: &'a [KnownPack] diff --git a/pumpkin-protocol/src/server/config/s_plugin_message.rs b/pumpkin-protocol/src/server/config/s_plugin_message.rs index d2341a9de..7007f35d8 100644 --- a/pumpkin-protocol/src/server/config/s_plugin_message.rs +++ b/pumpkin-protocol/src/server/config/s_plugin_message.rs @@ -1,8 +1,11 @@ +use pumpkin_macros::server_packet; + use crate::{ bytebuf::{ByteBuffer, DeserializerError}, Identifier, ServerPacket, }; +#[server_packet("configuration:custom_payload")] pub struct SPluginMessage { pub channel: Identifier, pub data: Vec, diff --git a/pumpkin-protocol/src/server/handshake/mod.rs b/pumpkin-protocol/src/server/handshake/mod.rs index cbed59db7..a1d743528 100644 --- a/pumpkin-protocol/src/server/handshake/mod.rs +++ b/pumpkin-protocol/src/server/handshake/mod.rs @@ -1,8 +1,11 @@ +use pumpkin_macros::server_packet; + use crate::{ bytebuf::{ByteBuffer, DeserializerError}, ConnectionState, ServerPacket, VarInt, }; +#[server_packet("handshake:intention")] pub struct SHandShake { pub protocol_version: VarInt, pub server_address: String, // 255 diff --git a/pumpkin-protocol/src/server/login/mod.rs b/pumpkin-protocol/src/server/login/mod.rs index aa0aca2ec..872f74bbc 100644 --- a/pumpkin-protocol/src/server/login/mod.rs +++ b/pumpkin-protocol/src/server/login/mod.rs @@ -3,19 +3,7 @@ mod s_login_response; mod s_login_start; mod s_plugin_response; -use num_derive::FromPrimitive; pub use s_encryption_response::*; pub use s_login_response::*; pub use s_login_start::*; pub use s_plugin_response::*; - -/// DO NOT CHANGE ORDER -/// This Enum has the exact order like vanilla, Vanilla parses their Packet IDs from the enum order. Its also way easier to port. -#[derive(FromPrimitive)] -pub enum ServerboundLoginPackets { - LoginStart, - EncryptionResponse, - PluginResponse, - LoginAcknowledged, - CookieResponse, -} diff --git a/pumpkin-protocol/src/server/login/s_encryption_response.rs b/pumpkin-protocol/src/server/login/s_encryption_response.rs index 6c3a5d3ef..06c224624 100644 --- a/pumpkin-protocol/src/server/login/s_encryption_response.rs +++ b/pumpkin-protocol/src/server/login/s_encryption_response.rs @@ -1,8 +1,11 @@ +use pumpkin_macros::server_packet; + use crate::{ bytebuf::{ByteBuffer, DeserializerError}, ServerPacket, VarInt, }; +#[server_packet("login:key")] pub struct SEncryptionResponse { pub shared_secret_length: VarInt, pub shared_secret: Vec, diff --git a/pumpkin-protocol/src/server/login/s_login_response.rs b/pumpkin-protocol/src/server/login/s_login_response.rs index 1a1d432d8..aaf250bf6 100644 --- a/pumpkin-protocol/src/server/login/s_login_response.rs +++ b/pumpkin-protocol/src/server/login/s_login_response.rs @@ -1,3 +1,6 @@ +use pumpkin_macros::server_packet; + // Acknowledgement to the Login Success packet sent to the server. #[derive(serde::Deserialize)] +#[server_packet("login:login_acknowledged")] pub struct SLoginAcknowledged {} diff --git a/pumpkin-protocol/src/server/login/s_login_start.rs b/pumpkin-protocol/src/server/login/s_login_start.rs index 41aaa96b9..7a4a724da 100644 --- a/pumpkin-protocol/src/server/login/s_login_start.rs +++ b/pumpkin-protocol/src/server/login/s_login_start.rs @@ -1,8 +1,11 @@ +use pumpkin_macros::server_packet; + use crate::{ bytebuf::{ByteBuffer, DeserializerError}, ServerPacket, }; +#[server_packet("login:hello")] pub struct SLoginStart { pub name: String, // 16 pub uuid: uuid::Uuid, diff --git a/pumpkin-protocol/src/server/login/s_plugin_response.rs b/pumpkin-protocol/src/server/login/s_plugin_response.rs index 9f3ec74ec..24656471e 100644 --- a/pumpkin-protocol/src/server/login/s_plugin_response.rs +++ b/pumpkin-protocol/src/server/login/s_plugin_response.rs @@ -3,7 +3,9 @@ use crate::{ ServerPacket, VarInt, }; use bytes::BytesMut; +use pumpkin_macros::server_packet; +#[server_packet("login:custom_query_answer")] pub struct SLoginPluginResponse { pub message_id: VarInt, pub data: Option, diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs index 0c1f9b9d1..6d97dd3d6 100644 --- a/pumpkin-protocol/src/server/play/mod.rs +++ b/pumpkin-protocol/src/server/play/mod.rs @@ -20,7 +20,6 @@ mod s_swing_arm; mod s_use_item; mod s_use_item_on; -use num_derive::FromPrimitive; pub use s_chat_command::*; pub use s_chat_message::*; pub use s_click_container::*; @@ -42,72 +41,3 @@ pub use s_set_held_item::*; pub use s_swing_arm::*; pub use s_use_item::*; pub use s_use_item_on::*; - -/// DO NOT CHANGE ORDER -/// This Enum has the exact order like vanilla, Vanilla parses their Packet IDs from the enum order. Its also way easier to port. -#[derive(FromPrimitive)] -pub enum ServerboundPlayPackets { - TeleportConfirm, - QueryBlockNbt, - SelectBundleItem, - SetDifficulty, - ChatAck, - ChatCommandUnsigned, - ChatCommand, - ChatMessage, - ChatSessionUpdate, - ChunkBatchAck, - ClientStatus, - ClientTickEnd, - ClientSettings, - TabComplete, - ConfigurationAck, - ClickWindowButton, - ClickWindow, - CloseWindow, - SlotStateChange, - CookieResponse, - PluginMessage, - DebugSampleSubscription, - EditBook, - QueryEntityNbt, - InteractEntity, - GenerateStructure, - KeepAlive, - LockDifficulty, - PlayerPosition, - PlayerPositionAndRotation, - PlayerRotation, - PlayerFlying, - - VehicleMove, - SteerBoat, - PickItem, - DebugPing, - CraftRecipeRequest, - PlayerAbilities, - PlayerDigging, - EntityAction, - PlayerInput, - Pong, - SetRecipeBookState, - SetDisplayedRecipe, - NameItem, - ResourcePackStatus, - AdvancementTab, - SelectTrade, - SetBeaconEffect, - HeldItemChange, - - UpdateCommandBlock, - UpdateCommandBlockMinecart, - CreativeInventoryAction, - UpdateJigsawBlock, - UpdateStructureBlock, - UpdateSign, - - Animation, - Spectate, - PlayerBlockPlacement, - UseItem, -} diff --git a/pumpkin-protocol/src/server/play/s_chat_command.rs b/pumpkin-protocol/src/server/play/s_chat_command.rs index e12bcdd89..c5c572cfb 100644 --- a/pumpkin-protocol/src/server/play/s_chat_command.rs +++ b/pumpkin-protocol/src/server/play/s_chat_command.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("play:chat_command")] pub struct SChatCommand { pub command: String, } diff --git a/pumpkin-protocol/src/server/play/s_chat_message.rs b/pumpkin-protocol/src/server/play/s_chat_message.rs index 58d3179b4..a8e61d746 100644 --- a/pumpkin-protocol/src/server/play/s_chat_message.rs +++ b/pumpkin-protocol/src/server/play/s_chat_message.rs @@ -1,4 +1,5 @@ use bytes::Bytes; +use pumpkin_macros::server_packet; use crate::{ bytebuf::{ByteBuffer, DeserializerError}, @@ -6,6 +7,7 @@ use crate::{ }; // derive(Deserialize)] +#[server_packet("play:chat")] pub struct SChatMessage { pub message: String, pub timestamp: i64, diff --git a/pumpkin-protocol/src/server/play/s_click_container.rs b/pumpkin-protocol/src/server/play/s_click_container.rs index f82aca1d3..8de3f8a79 100644 --- a/pumpkin-protocol/src/server/play/s_click_container.rs +++ b/pumpkin-protocol/src/server/play/s_click_container.rs @@ -1,9 +1,11 @@ use crate::slot::Slot; use crate::VarInt; +use pumpkin_macros::server_packet; use serde::de::SeqAccess; use serde::{de, Deserialize}; #[derive(Debug)] +#[server_packet("play:container_click")] pub struct SClickContainer { pub window_id: VarInt, pub state_id: VarInt, diff --git a/pumpkin-protocol/src/server/play/s_client_information.rs b/pumpkin-protocol/src/server/play/s_client_information.rs index b93760c2b..b16be1380 100644 --- a/pumpkin-protocol/src/server/play/s_client_information.rs +++ b/pumpkin-protocol/src/server/play/s_client_information.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("play:client_information")] pub struct SClientInformationPlay { pub locale: String, // 16 pub view_distance: i8, diff --git a/pumpkin-protocol/src/server/play/s_close_container.rs b/pumpkin-protocol/src/server/play/s_close_container.rs index 1c6140195..d6f97dadc 100644 --- a/pumpkin-protocol/src/server/play/s_close_container.rs +++ b/pumpkin-protocol/src/server/play/s_close_container.rs @@ -1,8 +1,10 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; use crate::VarInt; #[derive(Deserialize)] +#[server_packet("play:container_close")] pub struct SCloseContainer { pub window_id: VarInt, } diff --git a/pumpkin-protocol/src/server/play/s_confirm_teleport.rs b/pumpkin-protocol/src/server/play/s_confirm_teleport.rs index 2ee49d02a..b6f724e26 100644 --- a/pumpkin-protocol/src/server/play/s_confirm_teleport.rs +++ b/pumpkin-protocol/src/server/play/s_confirm_teleport.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("play:accept_teleportation")] pub struct SConfirmTeleport { pub teleport_id: VarInt, } diff --git a/pumpkin-protocol/src/server/play/s_interact.rs b/pumpkin-protocol/src/server/play/s_interact.rs index 4350812a3..9a1a5d7b5 100644 --- a/pumpkin-protocol/src/server/play/s_interact.rs +++ b/pumpkin-protocol/src/server/play/s_interact.rs @@ -1,8 +1,10 @@ use num_derive::FromPrimitive; use num_traits::FromPrimitive; +use pumpkin_macros::server_packet; use crate::{bytebuf::DeserializerError, ServerPacket, VarInt}; +#[server_packet("play:interact")] pub struct SInteract { pub entity_id: VarInt, pub typ: VarInt, diff --git a/pumpkin-protocol/src/server/play/s_keep_alive.rs b/pumpkin-protocol/src/server/play/s_keep_alive.rs index d49b7ecb5..714aaa134 100644 --- a/pumpkin-protocol/src/server/play/s_keep_alive.rs +++ b/pumpkin-protocol/src/server/play/s_keep_alive.rs @@ -1,6 +1,8 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; #[derive(Deserialize)] +#[server_packet("play:keep_alive")] pub struct SKeepAlive { pub keep_alive_id: i64, } diff --git a/pumpkin-protocol/src/server/play/s_ping_request.rs b/pumpkin-protocol/src/server/play/s_ping_request.rs index 2b52299ea..77655ed3e 100644 --- a/pumpkin-protocol/src/server/play/s_ping_request.rs +++ b/pumpkin-protocol/src/server/play/s_ping_request.rs @@ -1,6 +1,8 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; #[derive(Deserialize)] +#[server_packet("play:ping_request")] pub struct SPlayPingRequest { pub payload: i64, } diff --git a/pumpkin-protocol/src/server/play/s_player_abilities.rs b/pumpkin-protocol/src/server/play/s_player_abilities.rs index 0de8efadd..0bd5c06ed 100644 --- a/pumpkin-protocol/src/server/play/s_player_abilities.rs +++ b/pumpkin-protocol/src/server/play/s_player_abilities.rs @@ -1,8 +1,10 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; //The vanilla client sends this packet when the player starts/stops flying. Bitmask 0x02 is set when the player is flying. #[derive(Deserialize)] +#[server_packet("play:player_abilities")] pub struct SPlayerAbilities { pub flags: i8, } diff --git a/pumpkin-protocol/src/server/play/s_player_action.rs b/pumpkin-protocol/src/server/play/s_player_action.rs index f53ca006d..b8d774dc2 100644 --- a/pumpkin-protocol/src/server/play/s_player_action.rs +++ b/pumpkin-protocol/src/server/play/s_player_action.rs @@ -1,9 +1,11 @@ use num_derive::FromPrimitive; use pumpkin_core::math::position::WorldPosition; +use pumpkin_macros::server_packet; use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("play:player_action")] pub struct SPlayerAction { pub status: VarInt, pub location: WorldPosition, diff --git a/pumpkin-protocol/src/server/play/s_player_command.rs b/pumpkin-protocol/src/server/play/s_player_command.rs index e37011200..aeafcf153 100644 --- a/pumpkin-protocol/src/server/play/s_player_command.rs +++ b/pumpkin-protocol/src/server/play/s_player_command.rs @@ -1,7 +1,9 @@ use num_derive::FromPrimitive; +use pumpkin_macros::server_packet; use crate::{bytebuf::DeserializerError, ServerPacket, VarInt}; +#[server_packet("play:player_command")] pub struct SPlayerCommand { pub entity_id: VarInt, pub action: VarInt, diff --git a/pumpkin-protocol/src/server/play/s_player_ground.rs b/pumpkin-protocol/src/server/play/s_player_ground.rs index 0c167d829..dca0d17ee 100644 --- a/pumpkin-protocol/src/server/play/s_player_ground.rs +++ b/pumpkin-protocol/src/server/play/s_player_ground.rs @@ -1,6 +1,8 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; #[derive(Deserialize)] +#[server_packet("play:move_player_status_only")] pub struct SSetPlayerGround { pub on_ground: bool, } diff --git a/pumpkin-protocol/src/server/play/s_player_position.rs b/pumpkin-protocol/src/server/play/s_player_position.rs index ae17d46e1..729b406be 100644 --- a/pumpkin-protocol/src/server/play/s_player_position.rs +++ b/pumpkin-protocol/src/server/play/s_player_position.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("play:move_player_pos")] pub struct SPlayerPosition { pub x: f64, pub feet_y: f64, diff --git a/pumpkin-protocol/src/server/play/s_player_position_rotation.rs b/pumpkin-protocol/src/server/play/s_player_position_rotation.rs index e83c57bc9..a97a68ed5 100644 --- a/pumpkin-protocol/src/server/play/s_player_position_rotation.rs +++ b/pumpkin-protocol/src/server/play/s_player_position_rotation.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("play:move_player_pos_rot")] pub struct SPlayerPositionRotation { pub x: f64, pub feet_y: f64, diff --git a/pumpkin-protocol/src/server/play/s_player_rotation.rs b/pumpkin-protocol/src/server/play/s_player_rotation.rs index 8a8ec4aab..ac2acafa8 100644 --- a/pumpkin-protocol/src/server/play/s_player_rotation.rs +++ b/pumpkin-protocol/src/server/play/s_player_rotation.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("play:move_player_rot")] pub struct SPlayerRotation { pub yaw: f32, pub pitch: f32, diff --git a/pumpkin-protocol/src/server/play/s_set_creative_slot.rs b/pumpkin-protocol/src/server/play/s_set_creative_slot.rs index f35318bb3..0dff80b44 100644 --- a/pumpkin-protocol/src/server/play/s_set_creative_slot.rs +++ b/pumpkin-protocol/src/server/play/s_set_creative_slot.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::slot::Slot; #[derive(serde::Deserialize, Debug)] +#[server_packet("play:set_creative_mode_slot")] pub struct SSetCreativeSlot { pub slot: i16, pub clicked_item: Slot, diff --git a/pumpkin-protocol/src/server/play/s_set_held_item.rs b/pumpkin-protocol/src/server/play/s_set_held_item.rs index 2bf752878..05117dd29 100644 --- a/pumpkin-protocol/src/server/play/s_set_held_item.rs +++ b/pumpkin-protocol/src/server/play/s_set_held_item.rs @@ -1,6 +1,8 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; #[derive(Deserialize)] +#[server_packet("play:pick_item")] pub struct SSetHeldItem { pub slot: i16, } diff --git a/pumpkin-protocol/src/server/play/s_swing_arm.rs b/pumpkin-protocol/src/server/play/s_swing_arm.rs index 65d69bd34..0f7d0f16e 100644 --- a/pumpkin-protocol/src/server/play/s_swing_arm.rs +++ b/pumpkin-protocol/src/server/play/s_swing_arm.rs @@ -1,6 +1,9 @@ +use pumpkin_macros::server_packet; + use crate::VarInt; #[derive(serde::Deserialize)] +#[server_packet("play:swing")] pub struct SSwingArm { pub hand: VarInt, } diff --git a/pumpkin-protocol/src/server/play/s_use_item.rs b/pumpkin-protocol/src/server/play/s_use_item.rs index 933e66b78..7035fd0a9 100644 --- a/pumpkin-protocol/src/server/play/s_use_item.rs +++ b/pumpkin-protocol/src/server/play/s_use_item.rs @@ -1,8 +1,10 @@ +use pumpkin_macros::server_packet; use serde::Deserialize; use crate::VarInt; #[derive(Deserialize)] +#[server_packet("play:use_item")] pub struct SUseItem { // 0 for main hand, 1 for off hand pub hand: VarInt, diff --git a/pumpkin-protocol/src/server/play/s_use_item_on.rs b/pumpkin-protocol/src/server/play/s_use_item_on.rs index a4338ad33..3e16d282c 100644 --- a/pumpkin-protocol/src/server/play/s_use_item_on.rs +++ b/pumpkin-protocol/src/server/play/s_use_item_on.rs @@ -1,9 +1,11 @@ use pumpkin_core::math::position::WorldPosition; +use pumpkin_macros::server_packet; use serde::Deserialize; use crate::VarInt; #[derive(Deserialize)] +#[server_packet("play:use_item_on")] pub struct SUseItemOn { pub hand: VarInt, pub location: WorldPosition, diff --git a/pumpkin-protocol/src/server/status/mod.rs b/pumpkin-protocol/src/server/status/mod.rs index 008bc5e5d..fb6b04ab5 100644 --- a/pumpkin-protocol/src/server/status/mod.rs +++ b/pumpkin-protocol/src/server/status/mod.rs @@ -1,14 +1,5 @@ mod s_ping_request; mod s_status_request; -use num_derive::FromPrimitive; pub use s_ping_request::*; pub use s_status_request::*; - -/// DO NOT CHANGE ORDER -/// This Enum has the exact order like vanilla, Vanilla parses their Packet IDs from the enum order. Its also way easier to port. -#[derive(FromPrimitive)] -pub enum ServerboundStatusPackets { - StatusRequest, - PingRequest, -} diff --git a/pumpkin-protocol/src/server/status/s_ping_request.rs b/pumpkin-protocol/src/server/status/s_ping_request.rs index 33054d22f..b8fd75c16 100644 --- a/pumpkin-protocol/src/server/status/s_ping_request.rs +++ b/pumpkin-protocol/src/server/status/s_ping_request.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("status:ping_request")] pub struct SStatusPingRequest { pub payload: i64, } diff --git a/pumpkin-protocol/src/server/status/s_status_request.rs b/pumpkin-protocol/src/server/status/s_status_request.rs index ecd3ba85d..9d96fcc66 100644 --- a/pumpkin-protocol/src/server/status/s_status_request.rs +++ b/pumpkin-protocol/src/server/status/s_status_request.rs @@ -1,4 +1,7 @@ +use pumpkin_macros::server_packet; + #[derive(serde::Deserialize)] +#[server_packet("status:status_request")] pub struct SStatusRequest { // empty } diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 8e4065c5b..12f018f77 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -14,25 +14,18 @@ use crate::{ use authentication::GameProfile; use crossbeam::atomic::AtomicCell; -use num_traits::FromPrimitive; use pumpkin_config::compression::CompressionInfo; use pumpkin_core::text::TextComponent; use pumpkin_protocol::{ - bytebuf::DeserializerError, + bytebuf::{packet_id::Packet, DeserializerError}, client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, packet_decoder::PacketDecoder, packet_encoder::{PacketEncodeError, PacketEncoder}, server::{ - config::{ - SAcknowledgeFinishConfig, SClientInformationConfig, SKnownPacks, SPluginMessage, - ServerboundConfigPackets, - }, + config::{SAcknowledgeFinishConfig, SClientInformationConfig, SKnownPacks, SPluginMessage}, handshake::SHandShake, - login::{ - SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart, - ServerboundLoginPackets, - }, - status::{SStatusPingRequest, SStatusRequest, ServerboundStatusPackets}, + login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart}, + status::{SStatusPingRequest, SStatusRequest}, }, ClientPacket, ConnectionState, RawPacket, ServerPacket, }; @@ -397,24 +390,24 @@ impl Client { ) -> Result<(), DeserializerError> { log::debug!("Handling status group"); let bytebuf = &mut packet.bytebuf; - if let Some(packet) = ServerboundStatusPackets::from_i32(packet.id.0) { - match packet { - ServerboundStatusPackets::StatusRequest => { - self.handle_status_request(server, SStatusRequest::read(bytebuf)?) - .await; - } - ServerboundStatusPackets::PingRequest => { - self.handle_ping_request(SStatusPingRequest::read(bytebuf)?) - .await; - } - }; - } else { - log::error!( - "Failed to handle client packet id {:#04x} in Status State", - packet.id.0 - ); - return Err(DeserializerError::UnknownPacket); + match packet.id.0 { + SStatusRequest::PACKET_ID => { + self.handle_status_request(server, SStatusRequest::read(bytebuf)?) + .await; + } + SStatusPingRequest::PACKET_ID => { + self.handle_ping_request(SStatusPingRequest::read(bytebuf)?) + .await; + } + _ => { + log::error!( + "Failed to handle client packet id {:#04x} in Status State", + packet.id.0 + ); + return Err(DeserializerError::UnknownPacket); + } }; + Ok(()) } @@ -425,32 +418,30 @@ impl Client { ) -> Result<(), DeserializerError> { log::debug!("Handling login group for id"); let bytebuf = &mut packet.bytebuf; - if let Some(packet) = ServerboundLoginPackets::from_i32(packet.id.0) { - match packet { - ServerboundLoginPackets::LoginStart => { - self.handle_login_start(server, SLoginStart::read(bytebuf)?) - .await; - } - ServerboundLoginPackets::EncryptionResponse => { - self.handle_encryption_response(server, SEncryptionResponse::read(bytebuf)?) - .await; - } - ServerboundLoginPackets::PluginResponse => { - self.handle_plugin_response(SLoginPluginResponse::read(bytebuf)?) - .await; - } - ServerboundLoginPackets::LoginAcknowledged => { - self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)?) - .await; - } - ServerboundLoginPackets::CookieResponse => {} - }; - } else { - log::error!( - "Failed to handle client packet id {:#04x} in Login State", - packet.id.0 - ); - return Ok(()); + match packet.id.0 { + SLoginStart::PACKET_ID => { + self.handle_login_start(server, SLoginStart::read(bytebuf)?) + .await; + } + SEncryptionResponse::PACKET_ID => { + self.handle_encryption_response(server, SEncryptionResponse::read(bytebuf)?) + .await; + } + SLoginPluginResponse::PACKET_ID => { + self.handle_plugin_response(SLoginPluginResponse::read(bytebuf)?) + .await; + } + SLoginAcknowledged::PACKET_ID => { + self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)?) + .await; + } + _ => { + log::error!( + "Failed to handle client packet id {:#04x} in Login State", + packet.id.0 + ); + return Ok(()); + } }; Ok(()) } @@ -462,35 +453,29 @@ impl Client { ) -> Result<(), DeserializerError> { log::debug!("Handling config group"); let bytebuf = &mut packet.bytebuf; - if let Some(packet) = ServerboundConfigPackets::from_i32(packet.id.0) { - #[expect(clippy::match_same_arms)] - match packet { - ServerboundConfigPackets::ClientInformation => { - self.handle_client_information_config(SClientInformationConfig::read(bytebuf)?) - .await; - } - ServerboundConfigPackets::CookieResponse => {} - ServerboundConfigPackets::PluginMessage => { - self.handle_plugin_message(SPluginMessage::read(bytebuf)?) - .await; - } - ServerboundConfigPackets::AcknowledgedFinish => { - self.handle_config_acknowledged(&SAcknowledgeFinishConfig::read(bytebuf)?); - } - ServerboundConfigPackets::KeepAlive => {} - ServerboundConfigPackets::Pong => {} - ServerboundConfigPackets::ResourcePackResponse => {} - ServerboundConfigPackets::KnownPacks => { - self.handle_known_packs(server, SKnownPacks::read(bytebuf)?) - .await; - } - }; - } else { - log::error!( - "Failed to handle client packet id {:#04x} in Config State", - packet.id.0 - ); - return Err(DeserializerError::UnknownPacket); + match packet.id.0 { + SClientInformationConfig::PACKET_ID => { + self.handle_client_information_config(SClientInformationConfig::read(bytebuf)?) + .await; + } + SPluginMessage::PACKET_ID => { + self.handle_plugin_message(SPluginMessage::read(bytebuf)?) + .await; + } + SAcknowledgeFinishConfig::PACKET_ID => { + self.handle_config_acknowledged(&SAcknowledgeFinishConfig::read(bytebuf)?); + } + SKnownPacks::PACKET_ID => { + self.handle_known_packs(server, SKnownPacks::read(bytebuf)?) + .await; + } + _ => { + log::error!( + "Failed to handle client packet id {:#04x} in Config State", + packet.id.0 + ); + return Err(DeserializerError::UnknownPacket); + } }; Ok(()) } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 097b64bf9..a3d91428f 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -10,7 +10,7 @@ use std::{ use crossbeam::atomic::AtomicCell; use itertools::Itertools; use num_derive::FromPrimitive; -use num_traits::{FromPrimitive, ToPrimitive}; +use num_traits::ToPrimitive; use pumpkin_config::ADVANCED_CONFIG; use pumpkin_core::{ math::{boundingbox::BoundingBox, position::WorldPosition, vector2::Vector2, vector3::Vector3}, @@ -21,7 +21,7 @@ use pumpkin_entity::{entity_type::EntityType, EntityId}; use pumpkin_inventory::player::PlayerInventory; use pumpkin_macros::sound; use pumpkin_protocol::{ - bytebuf::DeserializerError, + bytebuf::packet_id::Packet, client::play::{ CGameEvent, CHurtAnimation, CKeepAlive, CPlayDisconnect, CPlayerAbilities, CPlayerInfoUpdate, CSetHealth, CSyncPlayerPosition, CSystemChatMessage, GameEvent, @@ -31,7 +31,7 @@ use pumpkin_protocol::{ SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract, SPlayerAbilities, SPlayerAction, SPlayerCommand, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUseItem, - SUseItemOn, ServerboundPlayPackets, + SUseItemOn, }, RawPacket, ServerPacket, SoundCategory, VarInt, }; @@ -653,124 +653,80 @@ impl Player { } } - #[expect(clippy::too_many_lines)] pub async fn handle_play_packet( self: &Arc, server: &Arc, packet: &mut RawPacket, ) -> Result<(), Box> { let bytebuf = &mut packet.bytebuf; - if let Some(packet) = ServerboundPlayPackets::from_i32(packet.id.0) { - #[expect(clippy::match_same_arms)] - match packet { - ServerboundPlayPackets::TeleportConfirm => { - self.handle_confirm_teleport(SConfirmTeleport::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::QueryBlockNbt => {} - ServerboundPlayPackets::SelectBundleItem => {} - ServerboundPlayPackets::SetDifficulty => {} - ServerboundPlayPackets::ChatAck => {} - ServerboundPlayPackets::ChatCommandUnsigned => { - self.handle_chat_command(server, SChatCommand::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::ChatCommand => {} - ServerboundPlayPackets::ChatMessage => { - self.handle_chat_message(SChatMessage::read(bytebuf)?).await; - } - ServerboundPlayPackets::ChatSessionUpdate => {} - ServerboundPlayPackets::ChunkBatchAck => {} - ServerboundPlayPackets::ClientStatus => {} - ServerboundPlayPackets::ClientTickEnd => {} - ServerboundPlayPackets::ClientSettings => { - self.handle_client_information(SClientInformationPlay::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::TabComplete => {} - ServerboundPlayPackets::ConfigurationAck => {} - ServerboundPlayPackets::ClickWindowButton => {} - ServerboundPlayPackets::ClickWindow => {} - ServerboundPlayPackets::CloseWindow => {} - ServerboundPlayPackets::SlotStateChange => {} - ServerboundPlayPackets::CookieResponse => {} - ServerboundPlayPackets::PluginMessage => {} - ServerboundPlayPackets::DebugSampleSubscription => {} - ServerboundPlayPackets::EditBook => {} - ServerboundPlayPackets::QueryEntityNbt => {} - ServerboundPlayPackets::InteractEntity => { - self.handle_interact(server, SInteract::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::GenerateStructure => {} - ServerboundPlayPackets::KeepAlive => { - self.handle_keep_alive(SKeepAlive::read(bytebuf)?).await; - } - ServerboundPlayPackets::LockDifficulty => {} - ServerboundPlayPackets::PlayerPosition => { - self.handle_position(SPlayerPosition::read(bytebuf)?).await; - } - ServerboundPlayPackets::PlayerPositionAndRotation => { - self.handle_position_rotation(SPlayerPositionRotation::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::PlayerRotation => { - self.handle_rotation(SPlayerRotation::read(bytebuf)?).await; - } - ServerboundPlayPackets::PlayerFlying => { - self.handle_player_ground(&SSetPlayerGround::read(bytebuf)?); - } - ServerboundPlayPackets::VehicleMove => {} - ServerboundPlayPackets::SteerBoat => {} - ServerboundPlayPackets::PickItem => {} - ServerboundPlayPackets::DebugPing => {} - ServerboundPlayPackets::CraftRecipeRequest => {} - ServerboundPlayPackets::PlayerAbilities => { - self.handle_player_abilities(SPlayerAbilities::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::PlayerDigging => { - self.handle_player_action(SPlayerAction::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::EntityAction => { - self.handle_player_command(SPlayerCommand::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::PlayerInput => {} - ServerboundPlayPackets::Pong => {} - ServerboundPlayPackets::SetRecipeBookState => {} - ServerboundPlayPackets::SetDisplayedRecipe => {} - ServerboundPlayPackets::NameItem => {} - ServerboundPlayPackets::ResourcePackStatus => {} - ServerboundPlayPackets::AdvancementTab => {} - ServerboundPlayPackets::SelectTrade => {} - ServerboundPlayPackets::SetBeaconEffect => {} - ServerboundPlayPackets::HeldItemChange => { - self.handle_set_held_item(SSetHeldItem::read(bytebuf)?) - .await; - } - ServerboundPlayPackets::UpdateCommandBlock => {} - ServerboundPlayPackets::UpdateCommandBlockMinecart => {} - ServerboundPlayPackets::CreativeInventoryAction => { - self.handle_set_creative_slot(SSetCreativeSlot::read(bytebuf)?) - .await?; - } - ServerboundPlayPackets::UpdateJigsawBlock => {} - ServerboundPlayPackets::UpdateStructureBlock => {} - ServerboundPlayPackets::UpdateSign => {} - ServerboundPlayPackets::Animation => { - self.handle_swing_arm(SSwingArm::read(bytebuf)?).await; - } - ServerboundPlayPackets::Spectate => {} - ServerboundPlayPackets::PlayerBlockPlacement => { - self.handle_use_item_on(SUseItemOn::read(bytebuf)?).await; - } - ServerboundPlayPackets::UseItem => self.handle_use_item(&SUseItem::read(bytebuf)?), - }; - } else { - log::error!("Failed to handle player packet id {:#04x}", packet.id.0); - return Err(Box::new(DeserializerError::UnknownPacket)); + match packet.id.0 { + SConfirmTeleport::PACKET_ID => { + self.handle_confirm_teleport(SConfirmTeleport::read(bytebuf)?) + .await; + } + SChatCommand::PACKET_ID => { + self.handle_chat_command(server, SChatCommand::read(bytebuf)?) + .await; + } + SChatMessage::PACKET_ID => { + self.handle_chat_message(SChatMessage::read(bytebuf)?).await; + } + SClientInformationPlay::PACKET_ID => { + self.handle_client_information(SClientInformationPlay::read(bytebuf)?) + .await; + } + SInteract::PACKET_ID => { + self.handle_interact(server, SInteract::read(bytebuf)?) + .await; + } + SKeepAlive::PACKET_ID => { + self.handle_keep_alive(SKeepAlive::read(bytebuf)?).await; + } + SPlayerPosition::PACKET_ID => { + self.handle_position(SPlayerPosition::read(bytebuf)?).await; + } + SPlayerPositionRotation::PACKET_ID => { + self.handle_position_rotation(SPlayerPositionRotation::read(bytebuf)?) + .await; + } + SPlayerRotation::PACKET_ID => { + self.handle_rotation(SPlayerRotation::read(bytebuf)?).await; + } + SSetPlayerGround::PACKET_ID => { + self.handle_player_ground(&SSetPlayerGround::read(bytebuf)?); + } + SPlayerAbilities::PACKET_ID => { + self.handle_player_abilities(SPlayerAbilities::read(bytebuf)?) + .await; + } + SPlayerAction::PACKET_ID => { + self.handle_player_action(SPlayerAction::read(bytebuf)?) + .await; + } + SPlayerCommand::PACKET_ID => { + self.handle_player_command(SPlayerCommand::read(bytebuf)?) + .await; + } + SSetHeldItem::PACKET_ID => { + self.handle_set_held_item(SSetHeldItem::read(bytebuf)?) + .await; + } + SSetCreativeSlot::PACKET_ID => { + self.handle_set_creative_slot(SSetCreativeSlot::read(bytebuf)?) + .await?; + } + SSwingArm::PACKET_ID => { + self.handle_swing_arm(SSwingArm::read(bytebuf)?).await; + } + SUseItemOn::PACKET_ID => { + self.handle_use_item_on(SUseItemOn::read(bytebuf)?).await; + } + SUseItem::PACKET_ID => self.handle_use_item(&SUseItem::read(bytebuf)?), + _ => { + log::warn!("Failed to handle player packet id {:#04x}", packet.id.0); + // TODO: We give an error if all play packets are implemented + // return Err(Box::new(DeserializerError::UnknownPacket)); + } }; Ok(()) }