From 692a88c16b8420f7c3df652505270db97d18b84c Mon Sep 17 00:00:00 2001 From: timvisee Date: Tue, 23 Nov 2021 00:20:30 +0100 Subject: [PATCH] Add some v1.16.5, v1.17, v1.17.1 types --- protocol/src/decoder.rs | 1 + protocol/src/version/mod.rs | 10 +- protocol/src/version/v1_14_4/game.rs | 28 +- protocol/src/version/v1_14_4/handshake.rs | 6 +- protocol/src/version/v1_14_4/login.rs | 22 +- protocol/src/version/v1_14_4/mod.rs | 5 + protocol/src/version/v1_14_4/status.rs | 14 +- protocol/src/version/v1_16_5/game.rs | 139 ++++++++++ protocol/src/version/v1_16_5/mod.rs | 6 + protocol/src/version/v1_17/game.rs | 132 +++++++++ protocol/src/version/v1_17/mod.rs | 6 + protocol/src/version/v1_17_1/game.rs | 317 +--------------------- protocol/src/version/v1_17_1/mod.rs | 5 + 13 files changed, 342 insertions(+), 349 deletions(-) create mode 100644 protocol/src/version/v1_16_5/game.rs create mode 100644 protocol/src/version/v1_16_5/mod.rs create mode 100644 protocol/src/version/v1_17/game.rs create mode 100644 protocol/src/version/v1_17/mod.rs diff --git a/protocol/src/decoder.rs b/protocol/src/decoder.rs index fee6ddf..503db3b 100644 --- a/protocol/src/decoder.rs +++ b/protocol/src/decoder.rs @@ -222,6 +222,7 @@ impl Decoder for Vec { } } +// TODO(timvisee): identifier decoder, we might want a custom type impl Decoder for Vec { type Output = Self; diff --git a/protocol/src/version/mod.rs b/protocol/src/version/mod.rs index d3dc8ac..cace214 100644 --- a/protocol/src/version/mod.rs +++ b/protocol/src/version/mod.rs @@ -1,4 +1,6 @@ pub mod v1_14_4; +pub mod v1_16_5; +pub mod v1_17; pub mod v1_17_1; /// Trait to obtain packet ID from packet data. @@ -8,11 +10,15 @@ pub trait PacketId { } #[macro_export] -macro_rules! trait_packet_id ( +macro_rules! set_packet_id ( ($type: ident, $id: expr) => ( + impl $type { + const PACKET_ID: u8 = $id; + } + impl PacketId for $type { fn packet_id(&self) -> u8 { - $id + Self::PACKET_ID } } ) diff --git a/protocol/src/version/v1_14_4/game.rs b/protocol/src/version/v1_14_4/game.rs index ee9ac40..0d42f8d 100644 --- a/protocol/src/version/v1_14_4/game.rs +++ b/protocol/src/version/v1_14_4/game.rs @@ -3,13 +3,25 @@ use crate::decoder::Decoder; use crate::decoder::DecoderReadExt; use crate::encoder::EncoderWriteExt; use crate::error::DecodeError; -use crate::{trait_packet_id, version::PacketId}; +use crate::{set_packet_id, version::PacketId}; use byteorder::{ReadBytesExt, WriteBytesExt}; use minecraft_protocol_derive::{Decoder, Encoder}; use nbt::CompoundTag; use std::io::Read; use uuid::Uuid; +set_packet_id!(ServerBoundChatMessage, 0x03); +set_packet_id!(ServerBoundKeepAlive, 0x0F); +set_packet_id!(ServerBoundAbilities, 0x19); + +set_packet_id!(ClientBoundChatMessage, 0x0F); +set_packet_id!(GameDisconnect, 0x1A); +set_packet_id!(ClientBoundKeepAlive, 0x21); +set_packet_id!(ChunkData, 0x21); +set_packet_id!(JoinGame, 0x25); +set_packet_id!(BossBar, 0x0D); +set_packet_id!(EntityAction, 0x1B); + pub enum GameServerBoundPacket { ServerBoundChatMessage(ServerBoundChatMessage), ServerBoundKeepAlive(ServerBoundKeepAlive), @@ -191,7 +203,7 @@ impl ServerBoundKeepAlive { } } -#[derive(Encoder, Decoder)] +#[derive(Encoder, Decoder, Debug)] pub struct ClientBoundKeepAlive { pub id: u64, } @@ -733,15 +745,3 @@ mod tests { assert!(abilities.creative_mode); } } - -trait_packet_id!(ServerBoundChatMessage, 0x03); -trait_packet_id!(ServerBoundKeepAlive, 0x0F); -trait_packet_id!(ServerBoundAbilities, 0x19); - -trait_packet_id!(ClientBoundChatMessage, 0x0F); -trait_packet_id!(GameDisconnect, 0x1A); -trait_packet_id!(ClientBoundKeepAlive, 0x21); -trait_packet_id!(ChunkData, 0x21); -trait_packet_id!(JoinGame, 0x25); -trait_packet_id!(BossBar, 0x0D); -trait_packet_id!(EntityAction, 0x1B); diff --git a/protocol/src/version/v1_14_4/handshake.rs b/protocol/src/version/v1_14_4/handshake.rs index c1a9ef8..82cc5a6 100644 --- a/protocol/src/version/v1_14_4/handshake.rs +++ b/protocol/src/version/v1_14_4/handshake.rs @@ -1,9 +1,11 @@ use crate::decoder::Decoder; use crate::error::DecodeError; -use crate::{trait_packet_id, version::PacketId}; +use crate::{set_packet_id, version::PacketId}; use minecraft_protocol_derive::{Decoder, Encoder}; use std::io::Read; +set_packet_id!(Handshake, 0x00); + pub enum HandshakeServerBoundPacket { Handshake(Handshake), } @@ -54,5 +56,3 @@ impl Handshake { HandshakeServerBoundPacket::Handshake(handshake) } } - -trait_packet_id!(Handshake, 0x00); diff --git a/protocol/src/version/v1_14_4/login.rs b/protocol/src/version/v1_14_4/login.rs index 84afb8f..eede43e 100644 --- a/protocol/src/version/v1_14_4/login.rs +++ b/protocol/src/version/v1_14_4/login.rs @@ -4,9 +4,19 @@ use uuid::Uuid; use crate::data::chat::Message; use crate::decoder::Decoder; use crate::error::DecodeError; -use crate::{trait_packet_id, version::PacketId}; +use crate::{set_packet_id, version::PacketId}; use minecraft_protocol_derive::{Decoder, Encoder}; +set_packet_id!(LoginStart, 0x00); +set_packet_id!(EncryptionResponse, 0x01); +set_packet_id!(LoginPluginResponse, 0x02); + +set_packet_id!(LoginDisconnect, 0x00); +set_packet_id!(EncryptionRequest, 0x01); +set_packet_id!(LoginSuccess, 0x02); +set_packet_id!(SetCompression, 0x03); +set_packet_id!(LoginPluginRequest, 0x04); + pub enum LoginServerBoundPacket { LoginStart(LoginStart), EncryptionResponse(EncryptionResponse), @@ -481,13 +491,3 @@ mod tests { ); } } - -trait_packet_id!(LoginStart, 0x00); -trait_packet_id!(EncryptionResponse, 0x01); -trait_packet_id!(LoginPluginResponse, 0x02); - -trait_packet_id!(LoginDisconnect, 0x00); -trait_packet_id!(EncryptionRequest, 0x01); -trait_packet_id!(LoginSuccess, 0x02); -trait_packet_id!(SetCompression, 0x03); -trait_packet_id!(LoginPluginRequest, 0x04); diff --git a/protocol/src/version/v1_14_4/mod.rs b/protocol/src/version/v1_14_4/mod.rs index 29a91c1..c0a452b 100644 --- a/protocol/src/version/v1_14_4/mod.rs +++ b/protocol/src/version/v1_14_4/mod.rs @@ -1,4 +1,9 @@ +// Spec: https://wiki.vg/index.php?title=Protocol&oldid=15346 + pub mod game; pub mod handshake; pub mod login; pub mod status; + +/// Minecraft protocol version. +pub const PROTOCOL: u32 = 498; diff --git a/protocol/src/version/v1_14_4/status.rs b/protocol/src/version/v1_14_4/status.rs index 2c5cfb2..7d789b5 100644 --- a/protocol/src/version/v1_14_4/status.rs +++ b/protocol/src/version/v1_14_4/status.rs @@ -1,10 +1,16 @@ use crate::data::server_status::*; use crate::decoder::Decoder; use crate::error::DecodeError; -use crate::{trait_packet_id, version::PacketId}; +use crate::{set_packet_id, version::PacketId}; use minecraft_protocol_derive::{Decoder, Encoder}; use std::io::Read; +set_packet_id!(StatusRequest, 0x00); +set_packet_id!(PingRequest, 0x01); + +set_packet_id!(StatusResponse, 0x00); +set_packet_id!(PingResponse, 0x01); + pub enum StatusServerBoundPacket { StatusRequest(StatusRequest), PingRequest(PingRequest), @@ -208,9 +214,3 @@ mod tests { ); } } - -trait_packet_id!(StatusRequest, 0x00); -trait_packet_id!(PingRequest, 0x01); - -trait_packet_id!(StatusResponse, 0x00); -trait_packet_id!(PingResponse, 0x01); diff --git a/protocol/src/version/v1_16_5/game.rs b/protocol/src/version/v1_16_5/game.rs new file mode 100644 index 0000000..0a3808e --- /dev/null +++ b/protocol/src/version/v1_16_5/game.rs @@ -0,0 +1,139 @@ +use crate::data::chat::Message; +use crate::error::DecodeError; +use crate::{set_packet_id, version::PacketId}; +use byteorder::{ReadBytesExt, WriteBytesExt}; +use minecraft_protocol_derive::{Decoder, Encoder}; +use nbt::CompoundTag; + +set_packet_id!(ServerBoundPluginMessage, 0x0B); +set_packet_id!(ServerBoundKeepAlive, 0x10); + +set_packet_id!(ClientBoundPluginMessage, 0x17); +set_packet_id!(NamedSoundEffect, 0x18); +set_packet_id!(JoinGame, 0x24); +set_packet_id!(PlayerPositionAndLook, 0x34); +set_packet_id!(Respawn, 0x39); +set_packet_id!(TimeUpdate, 0x4E); +set_packet_id!(Title, 0x4F); +set_packet_id!(ClientBoundKeepAlive, 0x1F); + +#[derive(Encoder, Decoder, Debug)] +pub struct ServerBoundPluginMessage { + #[data_type(max_length = 32767)] + pub channel: String, + pub data: Vec, +} + +#[derive(Encoder, Decoder)] +pub struct ServerBoundKeepAlive { + pub id: u64, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ClientBoundPluginMessage { + #[data_type(max_length = 32767)] + pub channel: String, + pub data: Vec, +} + +// TODO(timvisee): remove clone? +#[derive(Clone, Encoder, Decoder, Debug)] +pub struct NamedSoundEffect { + #[data_type(max_length = 32767)] + pub sound_name: String, + #[data_type(with = "var_int")] + pub sound_category: i32, + // Mulitplied by 8 + pub effect_pos_x: i32, + // Mulitplied by 8 + pub effect_pos_y: i32, + // Mulitplied by 8 + pub effect_pos_z: i32, + pub volume: f32, + pub pitch: f32, +} + +// TODO(timvisee): remove clone? +#[derive(Clone, Encoder, Decoder, Debug)] +pub struct JoinGame { + pub entity_id: u32, + pub hardcore: bool, + pub game_mode: u8, + pub previous_game_mode: u8, + // TODO: max string length: 32767 + pub world_names: Vec, + pub dimension_codec: CompoundTag, + pub dimension: CompoundTag, + #[data_type(max_length = 32767)] + pub world_name: String, + pub hashed_seed: i64, + #[data_type(with = "var_int")] + pub max_players: i32, + #[data_type(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct PlayerPositionAndLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: u8, + #[data_type(with = "var_int")] + pub teleport_id: i32, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct Respawn { + pub dimension: CompoundTag, + #[data_type(max_length = 32767)] + pub world_name: String, + pub hashed_seed: i64, + pub game_mode: u8, + pub previous_game_mode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct TimeUpdate { + pub world_age: i64, + pub time_of_day: i64, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct Title { + pub action: TitleAction, +} + +#[derive(Encoder, Decoder, Debug)] +pub enum TitleAction { + SetTitle { + text: Message, + }, + SetSubtitle { + text: Message, + }, + SetActionBar { + text: Message, + }, + SetTimesAndDisplay { + fade_in: i32, + stay: i32, + fade_out: i32, + }, + Hide, + Reset, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ClientBoundKeepAlive { + pub id: u64, +} diff --git a/protocol/src/version/v1_16_5/mod.rs b/protocol/src/version/v1_16_5/mod.rs new file mode 100644 index 0000000..e98eeba --- /dev/null +++ b/protocol/src/version/v1_16_5/mod.rs @@ -0,0 +1,6 @@ +// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16681 + +pub mod game; + +/// Minecraft protocol version. +pub const PROTOCOL: u32 = 754; diff --git a/protocol/src/version/v1_17/game.rs b/protocol/src/version/v1_17/game.rs new file mode 100644 index 0000000..4aa362e --- /dev/null +++ b/protocol/src/version/v1_17/game.rs @@ -0,0 +1,132 @@ +use crate::data::chat::Message; +use crate::{set_packet_id, version::PacketId}; +use minecraft_protocol_derive::{Decoder, Encoder}; +use nbt::CompoundTag; + +set_packet_id!(ServerBoundPluginMessage, 0x0A); +set_packet_id!(ServerBoundKeepAlive, 0x0F); + +set_packet_id!(ClientBoundPluginMessage, 0x18); +set_packet_id!(NamedSoundEffect, 0x19); +set_packet_id!(JoinGame, 0x26); +set_packet_id!(PlayerPositionAndLook, 0x38); +set_packet_id!(Respawn, 0x3D); +set_packet_id!(SetTitleSubtitle, 0x57); +set_packet_id!(TimeUpdate, 0x58); +set_packet_id!(SetTitleText, 0x59); +set_packet_id!(SetTitleTimes, 0x5A); +set_packet_id!(ClientBoundKeepAlive, 0x21); + +#[derive(Encoder, Decoder, Debug)] +pub struct ServerBoundPluginMessage { + #[data_type(max_length = 32767)] + pub channel: String, + pub data: Vec, +} + +#[derive(Encoder, Decoder)] +pub struct ServerBoundKeepAlive { + pub id: u64, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ClientBoundPluginMessage { + #[data_type(max_length = 32767)] + pub channel: String, + pub data: Vec, +} + +// TODO(timvisee): remove clone? +#[derive(Clone, Encoder, Decoder, Debug)] +pub struct NamedSoundEffect { + #[data_type(max_length = 32767)] + pub sound_name: String, + #[data_type(with = "var_int")] + pub sound_category: i32, + // Mulitplied by 8 + pub effect_pos_x: i32, + // Mulitplied by 8 + pub effect_pos_y: i32, + // Mulitplied by 8 + pub effect_pos_z: i32, + pub volume: f32, + pub pitch: f32, +} + +// TODO(timvisee): remove clone? +#[derive(Clone, Encoder, Decoder, Debug)] +pub struct JoinGame { + pub entity_id: u32, + pub hardcore: bool, + pub game_mode: u8, + pub previous_game_mode: u8, + // TODO: max string length: 32767 + pub world_names: Vec, + pub dimension_codec: CompoundTag, + pub dimension: CompoundTag, + #[data_type(max_length = 32767)] + pub world_name: String, + pub hashed_seed: i64, + #[data_type(with = "var_int")] + pub max_players: i32, + #[data_type(with = "var_int")] + pub view_distance: i32, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct Respawn { + pub dimension: CompoundTag, + #[data_type(max_length = 32767)] + pub world_name: String, + pub hashed_seed: i64, + pub game_mode: u8, + pub previous_game_mode: u8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct PlayerPositionAndLook { + pub x: f64, + pub y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub flags: u8, + #[data_type(with = "var_int")] + pub teleport_id: i32, + pub dismount_vehicle: bool, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct TimeUpdate { + pub world_age: i64, + pub time_of_day: i64, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct SetTitleText { + pub text: Message, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct SetTitleSubtitle { + pub text: Message, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct SetTitleTimes { + pub fade_in: i32, + pub stay: i32, + pub fade_out: i32, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ClientBoundKeepAlive { + pub id: u64, +} diff --git a/protocol/src/version/v1_17/mod.rs b/protocol/src/version/v1_17/mod.rs new file mode 100644 index 0000000..4f0c9c2 --- /dev/null +++ b/protocol/src/version/v1_17/mod.rs @@ -0,0 +1,6 @@ +// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16866 + +pub mod game; + +/// Minecraft protocol version. +pub const PROTOCOL: u32 = 755; diff --git a/protocol/src/version/v1_17_1/game.rs b/protocol/src/version/v1_17_1/game.rs index bc1316b..a04a0a5 100644 --- a/protocol/src/version/v1_17_1/game.rs +++ b/protocol/src/version/v1_17_1/game.rs @@ -1,313 +1,6 @@ -use crate::data::chat::Message; -use crate::decoder::Decoder; -use crate::error::DecodeError; -use crate::{trait_packet_id, version::PacketId}; -use minecraft_protocol_derive::Decoder; -use minecraft_protocol_derive::Encoder; -use nbt::CompoundTag; -use std::io::Read; - -// Re-export Minecraft 1.14.4 types -pub use super::super::v1_14_4::game::{ - BossBar, ChunkData, ClientBoundChatMessage, ClientBoundKeepAlive, EntityAction, GameDisconnect, - ServerBoundAbilities, ServerBoundChatMessage, ServerBoundKeepAlive, +// Re-export +pub use crate::version::v1_17::game::{ + ClientBoundKeepAlive, ClientBoundPluginMessage, JoinGame, NamedSoundEffect, + PlayerPositionAndLook, Respawn, ServerBoundKeepAlive, ServerBoundPluginMessage, + SetTitleSubtitle, SetTitleText, SetTitleTimes, TimeUpdate, }; - -pub enum GameServerBoundPacket { - ServerBoundChatMessage(ServerBoundChatMessage), - ServerBoundPluginMessage(ServerBoundPluginMessage), - ServerBoundKeepAlive(ServerBoundKeepAlive), - ServerBoundAbilities(ServerBoundAbilities), -} - -pub enum GameClientBoundPacket { - ClientBoundChatMessage(ClientBoundChatMessage), - JoinGame(JoinGame), - ClientBoundKeepAlive(ClientBoundKeepAlive), - ChunkData(ChunkData), - GameDisconnect(GameDisconnect), - BossBar(BossBar), - EntityAction(EntityAction), - - ClientBoundPluginMessage(ClientBoundPluginMessage), - NamedSoundEffect(NamedSoundEffect), - Respawn(Respawn), - PlayerPositionAndLook(PlayerPositionAndLook), - SpawnPosition(SpawnPosition), - SetTitleSubtitle(SetTitleSubtitle), - SetTitleText(SetTitleText), - TimeUpdate(TimeUpdate), - SetTitleTimes(SetTitleTimes), -} - -impl GameServerBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameServerBoundPacket::ServerBoundChatMessage(_) => 0x03, - GameServerBoundPacket::ServerBoundPluginMessage(_) => 0x0A, - GameServerBoundPacket::ServerBoundKeepAlive(_) => 0x0F, - GameServerBoundPacket::ServerBoundAbilities(_) => 0x19, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x03 => { - let chat_message = ServerBoundChatMessage::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundChatMessage(chat_message)) - } - 0x0A => { - let plugin_message = ServerBoundPluginMessage::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundPluginMessage( - plugin_message, - )) - } - 0x0F => { - let keep_alive = ServerBoundKeepAlive::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundKeepAlive(keep_alive)) - } - 0x19 => { - let abilities = ServerBoundAbilities::decode(reader)?; - - Ok(GameServerBoundPacket::ServerBoundAbilities(abilities)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -impl GameClientBoundPacket { - pub fn get_type_id(&self) -> u8 { - match self { - GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E, - GameClientBoundPacket::ClientBoundPluginMessage(_) => 0x18, - GameClientBoundPacket::NamedSoundEffect(_) => 0x19, - GameClientBoundPacket::GameDisconnect(_) => 0x1A, - GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20, - GameClientBoundPacket::ChunkData(_) => 0x21, - GameClientBoundPacket::JoinGame(_) => 0x25, - GameClientBoundPacket::BossBar(_) => 0x0D, - GameClientBoundPacket::EntityAction(_) => 0x1B, - GameClientBoundPacket::PlayerPositionAndLook(_) => 0x38, - GameClientBoundPacket::Respawn(_) => 0x3D, - GameClientBoundPacket::SpawnPosition(_) => 0x4B, - GameClientBoundPacket::SetTitleSubtitle(_) => 0x57, - GameClientBoundPacket::TimeUpdate(_) => 0x58, - GameClientBoundPacket::SetTitleText(_) => 0x59, - GameClientBoundPacket::SetTitleTimes(_) => 0x5A, - } - } - - pub fn decode(type_id: u8, reader: &mut R) -> Result { - match type_id { - 0x0E => { - let chat_message = ClientBoundChatMessage::decode(reader)?; - - Ok(GameClientBoundPacket::ClientBoundChatMessage(chat_message)) - } - 0x18 => { - let plugin_message = ClientBoundPluginMessage::decode(reader)?; - - Ok(GameClientBoundPacket::ClientBoundPluginMessage( - plugin_message, - )) - } - 0x19 => { - let named_sound_effect = NamedSoundEffect::decode(reader)?; - - Ok(GameClientBoundPacket::NamedSoundEffect(named_sound_effect)) - } - 0x1A => { - let game_disconnect = GameDisconnect::decode(reader)?; - - Ok(GameClientBoundPacket::GameDisconnect(game_disconnect)) - } - 0x20 => { - let keep_alive = ClientBoundKeepAlive::decode(reader)?; - - Ok(GameClientBoundPacket::ClientBoundKeepAlive(keep_alive)) - } - 0x21 => { - let chunk_data = ChunkData::decode(reader)?; - - Ok(GameClientBoundPacket::ChunkData(chunk_data)) - } - 0x25 => { - let join_game = JoinGame::decode(reader)?; - - Ok(GameClientBoundPacket::JoinGame(join_game)) - } - 0x3D => { - let respawn = Respawn::decode(reader)?; - - Ok(GameClientBoundPacket::Respawn(respawn)) - } - 0x38 => { - let player_position = PlayerPositionAndLook::decode(reader)?; - - Ok(GameClientBoundPacket::PlayerPositionAndLook( - player_position, - )) - } - 0x4B => { - let spawn_position = SpawnPosition::decode(reader)?; - - Ok(GameClientBoundPacket::SpawnPosition(spawn_position)) - } - 0x57 => { - let title_subtitle = SetTitleSubtitle::decode(reader)?; - - Ok(GameClientBoundPacket::SetTitleSubtitle(title_subtitle)) - } - 0x58 => { - let time_update = TimeUpdate::decode(reader)?; - - Ok(GameClientBoundPacket::TimeUpdate(time_update)) - } - 0x59 => { - let title_text = SetTitleText::decode(reader)?; - - Ok(GameClientBoundPacket::SetTitleText(title_text)) - } - 0x5A => { - let title_times = SetTitleTimes::decode(reader)?; - - Ok(GameClientBoundPacket::SetTitleTimes(title_times)) - } - _ => Err(DecodeError::UnknownPacketType { type_id }), - } - } -} - -// TODO(timvisee): implement new() -#[derive(Encoder, Decoder, Debug)] -pub struct ServerBoundPluginMessage { - #[data_type(max_length = 32767)] - pub channel: String, - pub data: Vec, -} - -// TODO(timvisee): implement new() -#[derive(Encoder, Decoder, Debug)] -pub struct ClientBoundPluginMessage { - #[data_type(max_length = 32767)] - pub channel: String, - pub data: Vec, -} - -// TODO(timvisee): implement new() -// TODO(timvisee): remove clone? -#[derive(Clone, Encoder, Decoder, Debug)] -pub struct NamedSoundEffect { - #[data_type(max_length = 32767)] - pub sound_name: String, - #[data_type(with = "var_int")] - pub sound_category: i32, - // Mulitplied by 8 - pub effect_pos_x: i32, - // Mulitplied by 8 - pub effect_pos_y: i32, - // Mulitplied by 8 - pub effect_pos_z: i32, - pub volume: f32, - pub pitch: f32, -} - -// TODO(timvisee): implement new() -// TODO(timvisee): remove clone? -#[derive(Clone, Encoder, Decoder, Debug)] -pub struct JoinGame { - pub entity_id: u32, - pub hardcore: bool, - pub game_mode: u8, - pub previous_game_mode: u8, - // TODO: max string length: 32767 - pub world_names: Vec, - pub dimension_codec: CompoundTag, - pub dimension: CompoundTag, - #[data_type(max_length = 32767)] - pub world_name: String, - pub hashed_seed: i64, - #[data_type(with = "var_int")] - pub max_players: i32, - #[data_type(with = "var_int")] - pub view_distance: i32, - pub reduced_debug_info: bool, - pub enable_respawn_screen: bool, - pub is_debug: bool, - pub is_flat: bool, -} - -// TODO(timvisee): implement new() -#[derive(Encoder, Decoder, Debug)] -pub struct Respawn { - pub dimension: CompoundTag, - #[data_type(max_length = 32767)] - pub world_name: String, - pub hashed_seed: i64, - pub game_mode: u8, - pub previous_game_mode: u8, - pub is_debug: bool, - pub is_flat: bool, - pub copy_metadata: bool, -} - -// TODO(timvisee): implement new() -#[derive(Encoder, Decoder, Debug)] -pub struct PlayerPositionAndLook { - pub x: f64, - pub y: f64, - pub z: f64, - pub yaw: f32, - pub pitch: f32, - pub flags: u8, - #[data_type(with = "var_int")] - pub teleport_id: i32, - pub dismount_vehicle: bool, -} - -// TODO(timvisee): implement new() -#[derive(Encoder, Decoder, Debug)] -pub struct TimeUpdate { - pub world_age: i64, - pub time_of_day: i64, -} - -#[derive(Encoder, Decoder, Debug)] -pub struct SetTitleText { - pub text: Message, -} - -#[derive(Encoder, Decoder, Debug)] -pub struct SetTitleSubtitle { - pub text: Message, -} - -#[derive(Encoder, Decoder, Debug)] -pub struct SetTitleTimes { - pub fade_in: i32, - pub stay: i32, - pub fade_out: i32, -} - -#[derive(Encoder, Decoder, Debug)] -pub struct SpawnPosition { - pub position: u64, - pub angle: f32, -} - -trait_packet_id!(ServerBoundPluginMessage, 0x0A); - -trait_packet_id!(ClientBoundPluginMessage, 0x18); -trait_packet_id!(NamedSoundEffect, 0x19); -trait_packet_id!(JoinGame, 0x26); -trait_packet_id!(PlayerPositionAndLook, 0x38); -trait_packet_id!(Respawn, 0x3D); -trait_packet_id!(SpawnPosition, 0x4B); -trait_packet_id!(SetTitleSubtitle, 0x57); -trait_packet_id!(TimeUpdate, 0x58); -trait_packet_id!(SetTitleText, 0x59); -trait_packet_id!(SetTitleTimes, 0x5A); diff --git a/protocol/src/version/v1_17_1/mod.rs b/protocol/src/version/v1_17_1/mod.rs index f7ee1cd..4601bea 100644 --- a/protocol/src/version/v1_17_1/mod.rs +++ b/protocol/src/version/v1_17_1/mod.rs @@ -1 +1,6 @@ +// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16918 + pub mod game; + +/// Minecraft protocol version. +pub const PROTOCOL: u32 = 756;