From 44ea6915db5a6b69439d34a5d207271db6195fdf Mon Sep 17 00:00:00 2001 From: Guac <60993440+guac420@users.noreply.github.com> Date: Fri, 3 Feb 2023 22:30:12 -0800 Subject: [PATCH] Implement remaining clientbound packets (#197) Aims to close #186 --- crates/valence/src/client.rs | 16 +- crates/valence/src/client/event.rs | 22 +- crates/valence/src/player_list.rs | 6 +- crates/valence_protocol/src/packets/c2s.rs | 36 +- crates/valence_protocol/src/packets/s2c.rs | 318 +++++++++++++++++- .../src/packets/s2c/map_data.rs | 111 ++++++ .../src/packets/s2c/message_signature.rs | 39 +++ .../src/packets/s2c/player_chat_message.rs | 45 +-- .../src/packets/s2c/sound_id.rs | 44 +++ .../src/packets/s2c/stop_sound.rs | 50 +++ .../src/packets/s2c/update_advancements.rs | 8 +- .../src/packets/s2c/update_teams.rs | 224 ++++++++++++ crates/valence_protocol/src/types.rs | 91 ++++- 13 files changed, 903 insertions(+), 107 deletions(-) create mode 100644 crates/valence_protocol/src/packets/s2c/map_data.rs create mode 100644 crates/valence_protocol/src/packets/s2c/message_signature.rs create mode 100644 crates/valence_protocol/src/packets/s2c/sound_id.rs create mode 100644 crates/valence_protocol/src/packets/s2c/stop_sound.rs create mode 100644 crates/valence_protocol/src/packets/s2c/update_teams.rs diff --git a/crates/valence/src/client.rs b/crates/valence/src/client.rs index a7ae287..c5f2f5c 100644 --- a/crates/valence/src/client.rs +++ b/crates/valence/src/client.rs @@ -431,7 +431,7 @@ impl Client { pub fn send_message(&mut self, msg: impl Into) { self.queue_packet(&SystemChatMessage { chat: msg.into(), - kind: VarInt(0), + overlay: false, }); } @@ -610,10 +610,12 @@ impl Client { let title = title.into(); let subtitle = subtitle.into(); - self.queue_packet(&SetTitleText(title)); + self.queue_packet(&SetTitleText { title_text: title }); if !subtitle.is_empty() { - self.queue_packet(&SetSubtitleText(subtitle)); + self.queue_packet(&SetSubtitleText { + subtitle_text: subtitle, + }); } if let Some(anim) = animation.into() { @@ -623,7 +625,9 @@ impl Client { /// Sets the action bar for this client. pub fn set_action_bar(&mut self, text: impl Into) { - self.queue_packet(&SetActionBarText(text.into())); + self.queue_packet(&SetActionBarText { + action_bar_text: text.into(), + }); } /// Sets the attack cooldown speed. @@ -1046,7 +1050,9 @@ impl Client { } else { if self.view_distance != self.old_view_distance { // Change the render distance fog. - send.append_packet(&SetRenderDistance(VarInt(self.view_distance.into())))?; + send.append_packet(&SetRenderDistance { + view_distance: VarInt(self.view_distance.into()), + })?; } if self.bits.respawn() { diff --git a/crates/valence/src/client/event.rs b/crates/valence/src/client/event.rs index 859ad34..38bc7e9 100644 --- a/crates/valence/src/client/event.rs +++ b/crates/valence/src/client/event.rs @@ -32,8 +32,7 @@ pub enum ClientEvent { }, ChangeDifficulty(Difficulty), MessageAcknowledgment { - last_seen: Vec<(Uuid, Box<[u8]>)>, - last_received: Option<(Uuid, Box<[u8]>)>, + message_count: i32, }, ChatCommand { command: Box, @@ -321,18 +320,9 @@ pub(super) fn next_event_fallible( position: p.position, transaction_id: p.transaction_id.0, }, - C2sPlayPacket::ChangeDifficulty(p) => ClientEvent::ChangeDifficulty(p.0), + C2sPlayPacket::ChangeDifficulty(p) => ClientEvent::ChangeDifficulty(p.new_difficulty), C2sPlayPacket::MessageAcknowledgmentC2s(p) => ClientEvent::MessageAcknowledgment { - last_seen: p - .0 - .last_seen - .into_iter() - .map(|entry| (entry.profile_id, entry.signature.into())) - .collect(), - last_received: p - .0 - .last_received - .map(|entry| (entry.profile_id, entry.signature.into())), + message_count: p.message_count.0, }, C2sPlayPacket::ChatCommand(p) => ClientEvent::ChatCommand { command: p.command.into(), @@ -429,7 +419,7 @@ pub(super) fn next_event_fallible( continue; } - C2sPlayPacket::LockDifficulty(p) => ClientEvent::LockDifficulty(p.0), + C2sPlayPacket::LockDifficulty(p) => ClientEvent::LockDifficulty(p.locked), C2sPlayPacket::SetPlayerPosition(p) => { if client.pending_teleports != 0 { continue; @@ -477,7 +467,7 @@ pub(super) fn next_event_fallible( continue; } - ClientEvent::SetPlayerOnGround(p.0) + ClientEvent::SetPlayerOnGround(p.on_ground) } C2sPlayPacket::MoveVehicleC2s(p) => { if client.pending_teleports != 0 { @@ -640,7 +630,7 @@ pub(super) fn next_event_fallible( position: p.position, lines: p.lines.map(From::from), }, - C2sPlayPacket::SwingArm(p) => ClientEvent::SwingArm(p.0), + C2sPlayPacket::SwingArm(p) => ClientEvent::SwingArm(p.hand), C2sPlayPacket::TeleportToEntity(p) => { ClientEvent::TeleportToEntity { target: p.target } } diff --git a/crates/valence/src/player_list.rs b/crates/valence/src/player_list.rs index 27be8d2..8ba715b 100644 --- a/crates/valence/src/player_list.rs +++ b/crates/valence/src/player_list.rs @@ -90,7 +90,9 @@ impl PlayerLists { if !pl.removed.is_empty() { writer - .write_packet(&PlayerInfoRemove(pl.removed.iter().cloned().collect())) + .write_packet(&PlayerInfoRemove { + players: pl.removed.iter().cloned().collect(), + }) .unwrap(); } @@ -471,7 +473,7 @@ impl PlayerList { .chain(self.removed.iter().cloned()) .collect(); - writer.write_packet(&PlayerInfoRemove(uuids)) + writer.write_packet(&PlayerInfoRemove { players: uuids }) } } diff --git a/crates/valence_protocol/src/packets/c2s.rs b/crates/valence_protocol/src/packets/c2s.rs index 2ffc715..6ba19d5 100644 --- a/crates/valence_protocol/src/packets/c2s.rs +++ b/crates/valence_protocol/src/packets/c2s.rs @@ -8,9 +8,8 @@ use crate::raw_bytes::RawBytes; use crate::types::{ Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags, CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand, - HandshakeNextState, MainHand, MessageAcknowledgment, PlayerInputFlags, RecipeBookId, - StructureBlockAction, StructureBlockFlags, StructureBlockMirror, StructureBlockMode, - StructureBlockRotation, + HandshakeNextState, MainHand, PlayerInputFlags, RecipeBookId, StructureBlockAction, + StructureBlockFlags, StructureBlockMirror, StructureBlockMode, StructureBlockRotation, }; use crate::username::Username; use crate::var_int::VarInt; @@ -120,11 +119,15 @@ pub mod play { #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x02] - pub struct ChangeDifficulty(pub Difficulty); + pub struct ChangeDifficulty { + pub new_difficulty: Difficulty, + } - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x03] - pub struct MessageAcknowledgmentC2s<'a>(pub MessageAcknowledgment<'a>); + pub struct MessageAcknowledgmentC2s { + pub message_count: VarInt, + } #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x04] @@ -133,8 +136,11 @@ pub mod play { pub timestamp: u64, pub salt: u64, pub argument_signatures: Vec>, - pub signed_preview: bool, - pub acknowledgement: MessageAcknowledgment<'a>, + pub message_count: VarInt, + // This is a bitset of 20; each bit represents one + // of the last 20 messages received and whether or not + // the message was acknowledged by the client + pub acknowledgement: &'a [u8; 3], } #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] @@ -249,7 +255,9 @@ pub mod play { #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x12] - pub struct LockDifficulty(pub bool); + pub struct LockDifficulty { + pub locked: bool, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x13] @@ -277,7 +285,9 @@ pub mod play { #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x16] - pub struct SetPlayerOnGround(pub bool); + pub struct SetPlayerOnGround { + pub on_ground: bool, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x17] @@ -474,7 +484,9 @@ pub mod play { #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x2f] - pub struct SwingArm(pub Hand); + pub struct SwingArm { + pub hand: Hand, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x30] @@ -506,7 +518,7 @@ pub mod play { ConfirmTeleport, QueryBlockEntityTag, ChangeDifficulty, - MessageAcknowledgmentC2s<'a>, + MessageAcknowledgmentC2s, ChatCommand<'a>, ChatMessage<'a>, ClientCommand, diff --git a/crates/valence_protocol/src/packets/s2c.rs b/crates/valence_protocol/src/packets/s2c.rs index 34c8141..15dad5a 100644 --- a/crates/valence_protocol/src/packets/s2c.rs +++ b/crates/valence_protocol/src/packets/s2c.rs @@ -9,9 +9,11 @@ use crate::item::ItemStack; use crate::raw_bytes::RawBytes; use crate::text::Text; use crate::types::{ - AttributeProperty, BossBarAction, ChunkDataBlockEntity, Difficulty, GameEventKind, GameMode, - GlobalPos, PlayerAbilitiesFlags, SignedProperty, SoundCategory, Statistic, - SyncPlayerPosLookFlags, TagGroup, + AttributeProperty, BossBarAction, ChatSuggestionAction, ChunkDataBlockEntity, + CommandSuggestionMatch, Difficulty, EntityEffectFlags, FeetOrEyes, GameEventKind, GameMode, + GlobalPos, Hand, LookAtEntity, MerchantTrade, PlayerAbilitiesFlags, SignedProperty, + SoundCategory, Statistic, SyncPlayerPosLookFlags, TagGroup, UpdateObjectiveMode, + UpdateScoreAction, }; use crate::username::Username; use crate::var_int::VarInt; @@ -20,12 +22,17 @@ use crate::LengthPrefixedArray; pub mod commands; pub mod declare_recipes; +pub mod map_data; +pub mod message_signature; pub mod particle; pub mod player_chat_message; pub mod player_info_update; pub mod set_equipment; +pub mod sound_id; +pub mod stop_sound; pub mod update_advancements; pub mod update_recipe_book; +pub mod update_teams; pub mod status { use super::*; @@ -104,15 +111,20 @@ pub mod login { pub mod play { use commands::Node; + pub use map_data::MapData; + pub use message_signature::MessageSignature; pub use particle::ParticleS2c; pub use player_chat_message::PlayerChatMessage; pub use player_info_update::PlayerInfoUpdate; pub use set_equipment::SetEquipment; + pub use sound_id::SoundId; + pub use stop_sound::StopSound; pub use update_advancements::UpdateAdvancements; pub use update_recipe_book::UpdateRecipeBook; use super::*; use crate::packets::s2c::declare_recipes::DeclaredRecipe; + use crate::packets::s2c::update_teams::UpdateTeamsMode; #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x00] @@ -183,6 +195,15 @@ pub mod play { pub data: Compound, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x08] + pub struct BlockAction { + pub position: BlockPos, + pub action_id: u8, + pub action_parameter: u8, + pub block_type: VarInt, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x09] pub struct BlockUpdate { @@ -210,6 +231,15 @@ pub mod play { pub reset: bool, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x0d] + pub struct CommandSuggestionResponse<'a> { + pub id: VarInt, + pub start: VarInt, + pub length: VarInt, + pub matches: Vec>, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x0e] pub struct Commands<'a> { @@ -275,6 +305,13 @@ pub mod play { pub cooldown_ticks: VarInt, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x14] + pub struct ChatSuggestions<'a> { + pub action: ChatSuggestionAction, + pub entries: Vec<&'a str>, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x15] pub struct PluginMessageS2c<'a> { @@ -282,12 +319,27 @@ pub mod play { pub data: RawBytes<'a>, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x16] + pub struct DeleteMessage<'a> { + pub signature: MessageSignature<'a>, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x17] pub struct DisconnectPlay { pub reason: Text, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x18] + pub struct DisguisedChatMessage { + pub message: Text, + pub chat_type: VarInt, + pub chat_type_name: Text, + pub target_name: Option, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x19] pub struct EntityEvent { @@ -295,6 +347,14 @@ pub mod play { pub entity_status: u8, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x1a] + pub struct PlaceRecipe<'a> { + pub window_id: u8, + pub recipe: Ident<&'a str>, + pub make_all: bool, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x1b] pub struct UnloadChunk { @@ -309,6 +369,14 @@ pub mod play { pub value: f32, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x1d] + pub struct OpenHorseScreen { + pub window_id: u8, + pub slot_count: VarInt, + pub entity_id: i32, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x1e] pub struct WorldBorderInitialize { @@ -431,6 +499,17 @@ pub mod play { pub last_death_location: Option<(Ident, BlockPos)>, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x26] + pub struct MerchantOffers { + pub window_id: VarInt, + pub trades: Vec, + pub villager_level: VarInt, + pub experience: VarInt, + pub is_regular_villager: bool, + pub can_restock: bool, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x27] pub struct UpdateEntityPosition { @@ -458,6 +537,20 @@ pub mod play { pub on_ground: bool, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x2a] + pub struct MoveVehicle { + pub position: [f64; 3], + pub yaw: f32, + pub pitch: f32, + } + + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x2b] + pub struct OpenBook { + pub hand: Hand, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x2c] pub struct OpenScreen { @@ -466,6 +559,25 @@ pub mod play { pub window_title: Text, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x2d] + pub struct OpenSignEditor { + pub location: BlockPos, + } + + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x2e] + pub struct PingPlay { + pub id: i32, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x2f] + pub struct PlaceGhostRecipe<'a> { + pub window_id: u8, + pub recipe: Ident<&'a str>, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x30] pub struct PlayerAbilitiesS2c { @@ -474,6 +586,19 @@ pub mod play { pub fov_modifier: f32, } + /// Unused by notchian clients. + #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x32] + pub struct EndCombat { + pub duration: VarInt, + pub entity_id: i32, + } + + /// Unused by notchian clients. + #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x33] + pub struct EnterCombat {} + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x34] pub struct CombatDeath { @@ -485,7 +610,17 @@ pub mod play { #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x35] - pub struct PlayerInfoRemove(pub Vec); + pub struct PlayerInfoRemove { + pub players: Vec, + } + + #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x37] + pub struct LookAt { + pub feet_eyes: FeetOrEyes, + pub target_position: [f64; 3], + pub entity_to_face: Option, + } #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x38] @@ -510,6 +645,13 @@ pub mod play { pub entity_ids: &'a [VarInt], } + #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x3b] + pub struct RemoveEntityEffect { + pub entity_id: VarInt, + pub effect_id: VarInt, + } + #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x3c] pub struct ResourcePackS2c<'a> { @@ -571,6 +713,12 @@ pub mod play { pub blocks: &'a [VarLong], } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x40] + pub struct SelectAdvancementsTab<'a> { + pub identifier: Option>, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x41] pub struct ServerData<'a> { @@ -581,7 +729,47 @@ pub mod play { #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x42] - pub struct SetActionBarText(pub Text); + pub struct SetActionBarText { + pub action_bar_text: Text, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x43] + pub struct SetBorderCenter { + pub xz_position: [f64; 2], + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x44] + pub struct SetBorderLerpSize { + pub old_diameter: f64, + pub new_diameter: f64, + pub speed: VarLong, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x45] + pub struct SetBorderSize { + pub diameter: f64, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x46] + pub struct SetBorderWarningDelay { + pub warning_time: VarInt, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x47] + pub struct SetBorderWarningDistance { + pub warning_blocks: VarInt, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x48] + pub struct SetCamera { + pub entity_id: VarInt, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x49] @@ -598,7 +786,9 @@ pub mod play { #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x4b] - pub struct SetRenderDistance(pub VarInt); + pub struct SetRenderDistance { + pub view_distance: VarInt, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x4c] @@ -607,6 +797,13 @@ pub mod play { pub angle: f32, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x4d] + pub struct DisplayObjective<'a> { + pub position: u8, + pub score_name: &'a str, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x4e] pub struct SetEntityMetadata<'a> { @@ -614,6 +811,13 @@ pub mod play { pub metadata: RawBytes<'a>, } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x4f] + pub struct LinkEntities { + pub attached_entity_id: i32, + pub holding_entity_id: i32, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x50] pub struct SetEntityVelocity { @@ -637,6 +841,13 @@ pub mod play { pub food_saturation: f32, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x54] + pub struct UpdateObjectives<'a> { + pub objective_name: &'a str, + pub mode: UpdateObjectiveMode, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x55] pub struct SetPassengers { @@ -645,9 +856,31 @@ pub mod play { pub passengers: Vec, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x56] + pub struct UpdateTeams<'a> { + pub team_name: &'a str, + pub mode: UpdateTeamsMode<'a>, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x57] + pub struct UpdateScore<'a> { + pub entity_name: &'a str, + pub action: UpdateScoreAction<'a>, + } + + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x58] + pub struct SetSimulationDistance { + pub simulation_distance: VarInt, + } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x59] - pub struct SetSubtitleText(pub Text); + pub struct SetSubtitleText { + pub subtitle_text: Text, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x5a] @@ -662,7 +895,9 @@ pub mod play { #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x5b] - pub struct SetTitleText(pub Text); + pub struct SetTitleText { + pub title_text: Text, + } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x5c] @@ -683,12 +918,13 @@ pub mod play { pub entity_id: VarInt, pub volume: f32, pub pitch: f32, + pub seed: i64, } #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x5e] - pub struct SoundEffect { - pub id: VarInt, + pub struct SoundEffect<'a> { + pub id: SoundId<'a>, pub category: SoundCategory, pub position: [i32; 3], pub volume: f32, @@ -700,8 +936,8 @@ pub mod play { #[packet_id = 0x60] pub struct SystemChatMessage { pub chat: Text, - /// Index into the chat type registry. - pub kind: VarInt, + /// Whether the message is in the actionbar or the chat. + pub overlay: bool, } #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] @@ -711,6 +947,13 @@ pub mod play { pub footer: Text, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x62] + pub struct TagQueryResponse { + pub transaction_id: VarInt, + pub nbt: Compound, + } + #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[packet_id = 0x63] pub struct PickupItem { @@ -742,6 +985,17 @@ pub mod play { pub features: Vec>, } + #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] + #[packet_id = 0x68] + pub struct EntityEffect { + pub entity_id: VarInt, + pub effect_id: VarInt, + pub amplifier: u8, + pub duration: VarInt, + pub flags: EntityEffectFlags, + pub factor_codec: Option, + } + #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] #[packet_id = 0x69] pub struct DeclareRecipes<'a> { @@ -750,7 +1004,9 @@ pub mod play { #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] #[packet_id = 0x6a] - pub struct UpdateTags<'a>(pub Vec>); + pub struct UpdateTags<'a> { + pub tags: Vec>, + } packet_enum! { #[derive(Clone)] @@ -763,21 +1019,28 @@ pub mod play { AcknowledgeBlockChange, SetBlockDestroyStage, BlockEntityData, + BlockAction, BlockUpdate, BossBar, SetDifficulty, ClearTitles, + CommandSuggestionResponse<'a>, Commands<'a>, CloseContainerS2c, SetContainerContent, SetContainerProperty, SetContainerSlot, SetCooldown, + ChatSuggestions<'a>, PluginMessageS2c<'a>, + DeleteMessage<'a>, DisconnectPlay, + DisguisedChatMessage, EntityEvent, + PlaceRecipe<'a>, UnloadChunk, GameEvent, + OpenHorseScreen, WorldBorderInitialize, KeepAliveS2c, ChunkDataAndUpdateLight<'a>, @@ -785,47 +1048,74 @@ pub mod play { UpdateLight, ParticleS2c, LoginPlay<'a>, + MapData<'a>, + MerchantOffers, UpdateEntityPosition, UpdateEntityPositionAndRotation, UpdateEntityRotation, + MoveVehicle, + OpenBook, OpenScreen, + OpenSignEditor, + PingPlay, + PlaceGhostRecipe<'a>, PlayerAbilitiesS2c, PlayerChatMessage<'a>, + EndCombat, + EnterCombat, CombatDeath, PlayerInfoRemove, PlayerInfoUpdate<'a>, + LookAt, SynchronizePlayerPosition, UpdateRecipeBook<'a>, RemoveEntities, + RemoveEntityEffect, ResourcePackS2c<'a>, Respawn<'a>, SetHeadRotation, UpdateSectionBlocks, + SelectAdvancementsTab<'a>, ServerData<'a>, SetActionBarText, + SetBorderCenter, + SetBorderLerpSize, + SetBorderSize, + SetBorderWarningDelay, + SetBorderWarningDistance, + SetCamera, SetHeldItemS2c, SetCenterChunk, SetRenderDistance, SetDefaultSpawnPosition, + DisplayObjective<'a>, SetEntityMetadata<'a>, + LinkEntities, SetEntityVelocity, SetEquipment, SetExperience, SetHealth, + UpdateObjectives<'a>, SetPassengers, + UpdateTeams<'a>, + UpdateScore<'a>, + SetSimulationDistance, SetSubtitleText, UpdateTime, SetTitleText, SetTitleAnimationTimes, EntitySoundEffect, - SoundEffect, + SoundEffect<'a>, + StopSound<'a>, SystemChatMessage, SetTabListHeaderAndFooter, + TagQueryResponse, PickupItem, TeleportEntity, UpdateAdvancements<'a>, UpdateAttributes<'a>, FeatureFlags<'a>, + EntityEffect, DeclareRecipes<'a>, UpdateTags<'a>, } diff --git a/crates/valence_protocol/src/packets/s2c/map_data.rs b/crates/valence_protocol/src/packets/s2c/map_data.rs new file mode 100644 index 0000000..86c62c5 --- /dev/null +++ b/crates/valence_protocol/src/packets/s2c/map_data.rs @@ -0,0 +1,111 @@ +use std::io::Write; + +use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, VarInt}; + +#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] +#[packet_id = 0x25] +pub struct MapData<'a> { + pub map_id: VarInt, + pub scale: i8, + pub locked: bool, + pub icons: Option>, + pub data: Option>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Icon { + pub icon_type: IconType, + /// In map coordinates; -128 for furthest left, +127 for furthest right + pub position: [i8; 2], + /// 0 is a vertical icon and increments by 22.5° + pub direction: i8, + pub display_name: Option, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum IconType { + WhiteArrow, + GreenArrow, + RedArrow, + BlueArrow, + WhiteCross, + RedPointer, + WhiteCircle, + SmallWhiteCircle, + Mansion, + Temple, + WhiteBanner, + OrangeBanner, + MagentaBanner, + LightBlueBanner, + YellowBanner, + LimeBanner, + PinkBanner, + GrayBanner, + LightGrayBanner, + CyanBanner, + PurpleBanner, + BlueBanner, + BrownBanner, + GreenBanner, + RedBanner, + BlackBanner, + TreasureMarker, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode)] +pub struct Data<'a> { + pub columns: u8, + pub rows: u8, + pub position: [i8; 2], + pub data: &'a [u8], +} + +impl Encode for MapData<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.map_id.encode(&mut w)?; + self.scale.encode(&mut w)?; + self.locked.encode(&mut w)?; + self.icons.encode(&mut w)?; + + match self.data { + None => 0u8.encode(&mut w)?, + Some(data) => data.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MapData<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let map_id = VarInt::decode(r)?; + let scale = i8::decode(r)?; + let locked = bool::decode(r)?; + let icons = >>::decode(r)?; + let columns = u8::decode(r)?; + + let data = if columns > 0 { + let rows = u8::decode(r)?; + let position = <[i8; 2]>::decode(r)?; + let data = <&'a [u8]>::decode(r)?; + + Some(Data { + columns, + rows, + position, + data, + }) + } else { + None + }; + + Ok(Self { + map_id, + scale, + locked, + icons, + data, + }) + } +} diff --git a/crates/valence_protocol/src/packets/s2c/message_signature.rs b/crates/valence_protocol/src/packets/s2c/message_signature.rs new file mode 100644 index 0000000..3060433 --- /dev/null +++ b/crates/valence_protocol/src/packets/s2c/message_signature.rs @@ -0,0 +1,39 @@ +use std::io::Write; + +use crate::{Decode, Encode, VarInt}; + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct MessageSignature<'a> { + pub message_id: i32, + pub signature: Option<&'a [u8; 256]>, +} + +impl<'a> Encode for MessageSignature<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + VarInt(self.message_id + 1).encode(&mut w)?; + + match self.signature { + None => {} + Some(signature) => signature.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MessageSignature<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let message_id = VarInt::decode(r)?.0 - 1; + + let signature = if message_id == -1 { + Some(<&[u8; 256]>::decode(r)?) + } else { + None + }; + + Ok(Self { + message_id, + signature, + }) + } +} diff --git a/crates/valence_protocol/src/packets/s2c/player_chat_message.rs b/crates/valence_protocol/src/packets/s2c/player_chat_message.rs index 733a6c7..21e7ddb 100644 --- a/crates/valence_protocol/src/packets/s2c/player_chat_message.rs +++ b/crates/valence_protocol/src/packets/s2c/player_chat_message.rs @@ -1,5 +1,6 @@ use std::io::Write; +use crate::packets::s2c::message_signature::MessageSignature; use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, Uuid, VarInt}; #[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] @@ -8,10 +9,10 @@ pub struct PlayerChatMessage<'a> { pub sender: Uuid, pub index: VarInt, pub message_signature: Option<&'a [u8; 256]>, - pub message: String, + pub message: &'a str, pub time_stamp: u64, pub salt: u64, - pub previous_messages: Vec>, + pub previous_messages: Vec>, pub unsigned_content: Option, pub filter_type: MessageFilterType, pub filter_type_bits: Option, @@ -20,12 +21,6 @@ pub struct PlayerChatMessage<'a> { pub network_target_name: Option, } -#[derive(Clone, PartialEq, Debug)] -pub struct PreviousMessage<'a> { - pub message_id: i32, - pub signature: Option<&'a [u8; 256]>, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] pub enum MessageFilterType { PassThrough, @@ -66,10 +61,10 @@ impl<'a> Decode<'a> for PlayerChatMessage<'a> { let sender = Uuid::decode(r)?; let index = VarInt::decode(r)?; let message_signature = Option::<&'a [u8; 256]>::decode(r)?; - let message = String::decode(r)?; + let message = <&str>::decode(r)?; let time_stamp = u64::decode(r)?; let salt = u64::decode(r)?; - let previous_messages = Vec::::decode(r)?; + let previous_messages = Vec::::decode(r)?; let unsigned_content = Option::::decode(r)?; let filter_type = MessageFilterType::decode(r)?; @@ -99,33 +94,3 @@ impl<'a> Decode<'a> for PlayerChatMessage<'a> { }) } } - -impl<'a> Encode for PreviousMessage<'a> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - VarInt(self.message_id + 1).encode(&mut w)?; - - match self.signature { - None => {} - Some(signature) => signature.encode(&mut w)?, - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for PreviousMessage<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let message_id = VarInt::decode(r)?.0 - 1; - - let signature = if message_id == -1 { - Some(<&[u8; 256]>::decode(r)?) - } else { - None - }; - - Ok(Self { - message_id, - signature, - }) - } -} diff --git a/crates/valence_protocol/src/packets/s2c/sound_id.rs b/crates/valence_protocol/src/packets/s2c/sound_id.rs new file mode 100644 index 0000000..66b267c --- /dev/null +++ b/crates/valence_protocol/src/packets/s2c/sound_id.rs @@ -0,0 +1,44 @@ +use std::io::Write; + +use crate::{Decode, Encode, Ident, VarInt}; + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum SoundId<'a> { + Direct { + id: Ident<&'a str>, + range: Option, + }, + Reference { + id: VarInt, + }, +} + +impl Encode for SoundId<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + SoundId::Direct { id, range } => { + VarInt(0).encode(&mut w)?; + id.encode(&mut w)?; + range.encode(&mut w)?; + } + SoundId::Reference { id } => VarInt(id.0 + 1).encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for SoundId<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let i = VarInt::decode(r)?.0; + + if i == 0 { + Ok(SoundId::Direct { + id: >::decode(r)?, + range: >::decode(r)?, + }) + } else { + Ok(SoundId::Reference { id: VarInt(i - 1) }) + } + } +} diff --git a/crates/valence_protocol/src/packets/s2c/stop_sound.rs b/crates/valence_protocol/src/packets/s2c/stop_sound.rs new file mode 100644 index 0000000..22235d3 --- /dev/null +++ b/crates/valence_protocol/src/packets/s2c/stop_sound.rs @@ -0,0 +1,50 @@ +use std::io::Write; + +use crate::types::SoundCategory; +use crate::{Decode, DecodePacket, Encode, EncodePacket, Ident}; + +#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] +#[packet_id = 0x5f] +pub struct StopSound<'a> { + pub source: Option, + pub sound: Option>, +} + +impl Encode for StopSound<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match (self.source, self.sound) { + (Some(source), Some(sound)) => { + 3i8.encode(&mut w)?; + source.encode(&mut w)?; + sound.encode(&mut w)?; + } + (None, Some(sound)) => { + 2i8.encode(&mut w)?; + sound.encode(&mut w)?; + } + (Some(source), None) => { + 1i8.encode(&mut w)?; + source.encode(&mut w)?; + } + _ => 0i8.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for StopSound<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let (source, sound) = match i8::decode(r)? { + 3 => ( + Some(SoundCategory::decode(r)?), + Some(>::decode(r)?), + ), + 2 => (None, Some(>::decode(r)?)), + 1 => (Some(SoundCategory::decode(r)?), None), + _ => (None, None), + }; + + Ok(Self { source, sound }) + } +} diff --git a/crates/valence_protocol/src/packets/s2c/update_advancements.rs b/crates/valence_protocol/src/packets/s2c/update_advancements.rs index 106df97..06a580a 100644 --- a/crates/valence_protocol/src/packets/s2c/update_advancements.rs +++ b/crates/valence_protocol/src/packets/s2c/update_advancements.rs @@ -32,8 +32,8 @@ pub struct AdvancementDisplay<'a> { pub frame_type: VarInt, pub flags: i32, pub background_texture: Option>, - pub x_coord: f64, - pub y_coord: f64, + pub x_coord: f32, + pub y_coord: f32, } #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] @@ -78,8 +78,8 @@ impl<'a> Decode<'a> for AdvancementDisplay<'a> { None }; - let x_coord = f64::decode(r)?; - let y_coord = f64::decode(r)?; + let x_coord = f32::decode(r)?; + let y_coord = f32::decode(r)?; Ok(Self { title, diff --git a/crates/valence_protocol/src/packets/s2c/update_teams.rs b/crates/valence_protocol/src/packets/s2c/update_teams.rs new file mode 100644 index 0000000..446c536 --- /dev/null +++ b/crates/valence_protocol/src/packets/s2c/update_teams.rs @@ -0,0 +1,224 @@ +use std::io::Write; + +use anyhow::bail; +use bitfield_struct::bitfield; + +use crate::{Decode, Encode, Text}; + +#[derive(Clone, PartialEq, Debug)] +pub enum UpdateTeamsMode<'a> { + CreateTeam { + team_display_name: Text, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Text, + team_suffix: Text, + entities: Vec<&'a str>, + }, + RemoveTeam, + UpdateTeamInfo { + team_display_name: Text, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Text, + team_suffix: Text, + }, + AddEntities { + entities: Vec<&'a str>, + }, + RemoveEntities { + entities: Vec<&'a str>, + }, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct TeamFlags { + pub friendly_fire: bool, + pub see_invisible_teammates: bool, + #[bits(6)] + _pad: u8, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum NameTagVisibility { + Always, + Never, + HideForOtherTeams, + HideForOwnTeam, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum CollisionRule { + Always, + Never, + PushOtherTeams, + PushOwnTeam, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum TeamColor { + Black, + DarkBlue, + DarkGreen, + DarkCyan, + DarkRed, + Purple, + Gold, + Gray, + DarkGray, + Blue, + BrightGreen, + Cyan, + Red, + Pink, + Yellow, + White, + Obfuscated, + Bold, + Strikethrough, + Underlined, + Italic, + Reset, +} + +impl Encode for UpdateTeamsMode<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + UpdateTeamsMode::CreateTeam { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + entities, + } => { + 0i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + entities.encode(&mut w)?; + } + UpdateTeamsMode::RemoveTeam => 1i8.encode(&mut w)?, + UpdateTeamsMode::UpdateTeamInfo { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + } => { + 2i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + } + UpdateTeamsMode::AddEntities { entities } => { + 3i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + UpdateTeamsMode::RemoveEntities { entities } => { + 4i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + } + Ok(()) + } +} + +impl<'a> Decode<'a> for UpdateTeamsMode<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + Ok(match i8::decode(r)? { + 0 => Self::CreateTeam { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + entities: Decode::decode(r)?, + }, + 1 => Self::RemoveTeam, + 2 => Self::UpdateTeamInfo { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + }, + 3 => Self::AddEntities { + entities: Decode::decode(r)?, + }, + 4 => Self::RemoveEntities { + entities: Decode::decode(r)?, + }, + n => bail!("unknown update teams action of {n}"), + }) + } +} diff --git a/crates/valence_protocol/src/types.rs b/crates/valence_protocol/src/types.rs index 34f59be..fe98cd4 100644 --- a/crates/valence_protocol/src/types.rs +++ b/crates/valence_protocol/src/types.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use uuid::Uuid; use valence_nbt::Compound; -use crate::{BlockPos, Decode, Encode, Ident, Text, VarInt}; +use crate::{BlockPos, Decode, Encode, Ident, ItemStack, Text, VarInt}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] pub enum HandshakeNextState { @@ -22,22 +22,10 @@ pub struct PublicKeyData<'a> { pub signature: &'a [u8], } -#[derive(Clone, Debug, Encode, Decode)] -pub struct MessageAcknowledgment<'a> { - pub last_seen: Vec>, - pub last_received: Option>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode)] -pub struct MessageAcknowledgmentEntry<'a> { - pub profile_id: Uuid, - pub signature: &'a [u8], -} - #[derive(Copy, Clone, Debug, Encode, Decode)] pub struct CommandArgumentSignature<'a> { pub argument_name: &'a str, - pub signature: &'a [u8], + pub signature: &'a [u8; 256], } #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] @@ -377,3 +365,78 @@ pub struct Statistic { pub statistic_id: VarInt, pub value: VarInt, } + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct EntityEffectFlags { + pub is_ambient: bool, + pub show_particles: bool, + pub show_icon: bool, + #[bits(5)] + _pad: u8, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum FeetOrEyes { + Feet, + Eyes, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct LookAtEntity { + pub entity_id: VarInt, + pub entity_feet_eyes: FeetOrEyes, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum UpdateObjectiveMode { + Create { + objective_value: Text, + objective_type: VarInt, + }, + Remove, + Update { + objective_value: Text, + objective_type: VarInt, + }, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum UpdateScoreAction<'a> { + Create { + objective_value: &'a str, + objective_type: VarInt, + }, + Remove, + Update { + objective_value: &'a str, + objective_type: VarInt, + }, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct CommandSuggestionMatch<'a> { + pub suggested_match: &'a str, + pub tooltip: Option, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct MerchantTrade { + pub input_one: Option, + pub output_item: Option, + pub input_two: Option, + pub trade_disabled: bool, + pub number_of_trade_uses: i32, + pub max_trade_uses: i32, + pub xp: i32, + pub special_price: i32, + pub price_multiplier: f32, + pub demand: i32, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ChatSuggestionAction { + Add, + Remove, + Set, +}