Implement remaining clientbound packets (#197)

Aims to close #186
This commit is contained in:
Guac 2023-02-03 22:30:12 -08:00 committed by GitHub
parent 9f8250d4f9
commit 44ea6915db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 903 additions and 107 deletions

View file

@ -431,7 +431,7 @@ impl<C: Config> Client<C> {
pub fn send_message(&mut self, msg: impl Into<Text>) { pub fn send_message(&mut self, msg: impl Into<Text>) {
self.queue_packet(&SystemChatMessage { self.queue_packet(&SystemChatMessage {
chat: msg.into(), chat: msg.into(),
kind: VarInt(0), overlay: false,
}); });
} }
@ -610,10 +610,12 @@ impl<C: Config> Client<C> {
let title = title.into(); let title = title.into();
let subtitle = subtitle.into(); let subtitle = subtitle.into();
self.queue_packet(&SetTitleText(title)); self.queue_packet(&SetTitleText { title_text: title });
if !subtitle.is_empty() { if !subtitle.is_empty() {
self.queue_packet(&SetSubtitleText(subtitle)); self.queue_packet(&SetSubtitleText {
subtitle_text: subtitle,
});
} }
if let Some(anim) = animation.into() { if let Some(anim) = animation.into() {
@ -623,7 +625,9 @@ impl<C: Config> Client<C> {
/// Sets the action bar for this client. /// Sets the action bar for this client.
pub fn set_action_bar(&mut self, text: impl Into<Text>) { pub fn set_action_bar(&mut self, text: impl Into<Text>) {
self.queue_packet(&SetActionBarText(text.into())); self.queue_packet(&SetActionBarText {
action_bar_text: text.into(),
});
} }
/// Sets the attack cooldown speed. /// Sets the attack cooldown speed.
@ -1046,7 +1050,9 @@ impl<C: Config> Client<C> {
} else { } else {
if self.view_distance != self.old_view_distance { if self.view_distance != self.old_view_distance {
// Change the render distance fog. // 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() { if self.bits.respawn() {

View file

@ -32,8 +32,7 @@ pub enum ClientEvent {
}, },
ChangeDifficulty(Difficulty), ChangeDifficulty(Difficulty),
MessageAcknowledgment { MessageAcknowledgment {
last_seen: Vec<(Uuid, Box<[u8]>)>, message_count: i32,
last_received: Option<(Uuid, Box<[u8]>)>,
}, },
ChatCommand { ChatCommand {
command: Box<str>, command: Box<str>,
@ -321,18 +320,9 @@ pub(super) fn next_event_fallible<C: Config>(
position: p.position, position: p.position,
transaction_id: p.transaction_id.0, 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 { C2sPlayPacket::MessageAcknowledgmentC2s(p) => ClientEvent::MessageAcknowledgment {
last_seen: p message_count: p.message_count.0,
.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())),
}, },
C2sPlayPacket::ChatCommand(p) => ClientEvent::ChatCommand { C2sPlayPacket::ChatCommand(p) => ClientEvent::ChatCommand {
command: p.command.into(), command: p.command.into(),
@ -429,7 +419,7 @@ pub(super) fn next_event_fallible<C: Config>(
continue; continue;
} }
C2sPlayPacket::LockDifficulty(p) => ClientEvent::LockDifficulty(p.0), C2sPlayPacket::LockDifficulty(p) => ClientEvent::LockDifficulty(p.locked),
C2sPlayPacket::SetPlayerPosition(p) => { C2sPlayPacket::SetPlayerPosition(p) => {
if client.pending_teleports != 0 { if client.pending_teleports != 0 {
continue; continue;
@ -477,7 +467,7 @@ pub(super) fn next_event_fallible<C: Config>(
continue; continue;
} }
ClientEvent::SetPlayerOnGround(p.0) ClientEvent::SetPlayerOnGround(p.on_ground)
} }
C2sPlayPacket::MoveVehicleC2s(p) => { C2sPlayPacket::MoveVehicleC2s(p) => {
if client.pending_teleports != 0 { if client.pending_teleports != 0 {
@ -640,7 +630,7 @@ pub(super) fn next_event_fallible<C: Config>(
position: p.position, position: p.position,
lines: p.lines.map(From::from), lines: p.lines.map(From::from),
}, },
C2sPlayPacket::SwingArm(p) => ClientEvent::SwingArm(p.0), C2sPlayPacket::SwingArm(p) => ClientEvent::SwingArm(p.hand),
C2sPlayPacket::TeleportToEntity(p) => { C2sPlayPacket::TeleportToEntity(p) => {
ClientEvent::TeleportToEntity { target: p.target } ClientEvent::TeleportToEntity { target: p.target }
} }

View file

@ -90,7 +90,9 @@ impl<C: Config> PlayerLists<C> {
if !pl.removed.is_empty() { if !pl.removed.is_empty() {
writer writer
.write_packet(&PlayerInfoRemove(pl.removed.iter().cloned().collect())) .write_packet(&PlayerInfoRemove {
players: pl.removed.iter().cloned().collect(),
})
.unwrap(); .unwrap();
} }
@ -471,7 +473,7 @@ impl<C: Config> PlayerList<C> {
.chain(self.removed.iter().cloned()) .chain(self.removed.iter().cloned())
.collect(); .collect();
writer.write_packet(&PlayerInfoRemove(uuids)) writer.write_packet(&PlayerInfoRemove { players: uuids })
} }
} }

View file

@ -8,9 +8,8 @@ use crate::raw_bytes::RawBytes;
use crate::types::{ use crate::types::{
Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags, Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags,
CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand, CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand,
HandshakeNextState, MainHand, MessageAcknowledgment, PlayerInputFlags, RecipeBookId, HandshakeNextState, MainHand, PlayerInputFlags, RecipeBookId, StructureBlockAction,
StructureBlockAction, StructureBlockFlags, StructureBlockMirror, StructureBlockMode, StructureBlockFlags, StructureBlockMirror, StructureBlockMode, StructureBlockRotation,
StructureBlockRotation,
}; };
use crate::username::Username; use crate::username::Username;
use crate::var_int::VarInt; use crate::var_int::VarInt;
@ -120,11 +119,15 @@ pub mod play {
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x02] #[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] #[packet_id = 0x03]
pub struct MessageAcknowledgmentC2s<'a>(pub MessageAcknowledgment<'a>); pub struct MessageAcknowledgmentC2s {
pub message_count: VarInt,
}
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x04] #[packet_id = 0x04]
@ -133,8 +136,11 @@ pub mod play {
pub timestamp: u64, pub timestamp: u64,
pub salt: u64, pub salt: u64,
pub argument_signatures: Vec<CommandArgumentSignature<'a>>, pub argument_signatures: Vec<CommandArgumentSignature<'a>>,
pub signed_preview: bool, pub message_count: VarInt,
pub acknowledgement: MessageAcknowledgment<'a>, // 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
@ -249,7 +255,9 @@ pub mod play {
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x12] #[packet_id = 0x12]
pub struct LockDifficulty(pub bool); pub struct LockDifficulty {
pub locked: bool,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x13] #[packet_id = 0x13]
@ -277,7 +285,9 @@ pub mod play {
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x16] #[packet_id = 0x16]
pub struct SetPlayerOnGround(pub bool); pub struct SetPlayerOnGround {
pub on_ground: bool,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x17] #[packet_id = 0x17]
@ -474,7 +484,9 @@ pub mod play {
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x2f] #[packet_id = 0x2f]
pub struct SwingArm(pub Hand); pub struct SwingArm {
pub hand: Hand,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x30] #[packet_id = 0x30]
@ -506,7 +518,7 @@ pub mod play {
ConfirmTeleport, ConfirmTeleport,
QueryBlockEntityTag, QueryBlockEntityTag,
ChangeDifficulty, ChangeDifficulty,
MessageAcknowledgmentC2s<'a>, MessageAcknowledgmentC2s,
ChatCommand<'a>, ChatCommand<'a>,
ChatMessage<'a>, ChatMessage<'a>,
ClientCommand, ClientCommand,

View file

@ -9,9 +9,11 @@ use crate::item::ItemStack;
use crate::raw_bytes::RawBytes; use crate::raw_bytes::RawBytes;
use crate::text::Text; use crate::text::Text;
use crate::types::{ use crate::types::{
AttributeProperty, BossBarAction, ChunkDataBlockEntity, Difficulty, GameEventKind, GameMode, AttributeProperty, BossBarAction, ChatSuggestionAction, ChunkDataBlockEntity,
GlobalPos, PlayerAbilitiesFlags, SignedProperty, SoundCategory, Statistic, CommandSuggestionMatch, Difficulty, EntityEffectFlags, FeetOrEyes, GameEventKind, GameMode,
SyncPlayerPosLookFlags, TagGroup, GlobalPos, Hand, LookAtEntity, MerchantTrade, PlayerAbilitiesFlags, SignedProperty,
SoundCategory, Statistic, SyncPlayerPosLookFlags, TagGroup, UpdateObjectiveMode,
UpdateScoreAction,
}; };
use crate::username::Username; use crate::username::Username;
use crate::var_int::VarInt; use crate::var_int::VarInt;
@ -20,12 +22,17 @@ use crate::LengthPrefixedArray;
pub mod commands; pub mod commands;
pub mod declare_recipes; pub mod declare_recipes;
pub mod map_data;
pub mod message_signature;
pub mod particle; pub mod particle;
pub mod player_chat_message; pub mod player_chat_message;
pub mod player_info_update; pub mod player_info_update;
pub mod set_equipment; pub mod set_equipment;
pub mod sound_id;
pub mod stop_sound;
pub mod update_advancements; pub mod update_advancements;
pub mod update_recipe_book; pub mod update_recipe_book;
pub mod update_teams;
pub mod status { pub mod status {
use super::*; use super::*;
@ -104,15 +111,20 @@ pub mod login {
pub mod play { pub mod play {
use commands::Node; use commands::Node;
pub use map_data::MapData;
pub use message_signature::MessageSignature;
pub use particle::ParticleS2c; pub use particle::ParticleS2c;
pub use player_chat_message::PlayerChatMessage; pub use player_chat_message::PlayerChatMessage;
pub use player_info_update::PlayerInfoUpdate; pub use player_info_update::PlayerInfoUpdate;
pub use set_equipment::SetEquipment; pub use set_equipment::SetEquipment;
pub use sound_id::SoundId;
pub use stop_sound::StopSound;
pub use update_advancements::UpdateAdvancements; pub use update_advancements::UpdateAdvancements;
pub use update_recipe_book::UpdateRecipeBook; pub use update_recipe_book::UpdateRecipeBook;
use super::*; use super::*;
use crate::packets::s2c::declare_recipes::DeclaredRecipe; use crate::packets::s2c::declare_recipes::DeclaredRecipe;
use crate::packets::s2c::update_teams::UpdateTeamsMode;
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x00] #[packet_id = 0x00]
@ -183,6 +195,15 @@ pub mod play {
pub data: Compound, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x09] #[packet_id = 0x09]
pub struct BlockUpdate { pub struct BlockUpdate {
@ -210,6 +231,15 @@ pub mod play {
pub reset: bool, 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<CommandSuggestionMatch<'a>>,
}
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x0e] #[packet_id = 0x0e]
pub struct Commands<'a> { pub struct Commands<'a> {
@ -275,6 +305,13 @@ pub mod play {
pub cooldown_ticks: VarInt, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x15] #[packet_id = 0x15]
pub struct PluginMessageS2c<'a> { pub struct PluginMessageS2c<'a> {
@ -282,12 +319,27 @@ pub mod play {
pub data: RawBytes<'a>, 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x17] #[packet_id = 0x17]
pub struct DisconnectPlay { pub struct DisconnectPlay {
pub reason: Text, 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<Text>,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x19] #[packet_id = 0x19]
pub struct EntityEvent { pub struct EntityEvent {
@ -295,6 +347,14 @@ pub mod play {
pub entity_status: u8, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x1b] #[packet_id = 0x1b]
pub struct UnloadChunk { pub struct UnloadChunk {
@ -309,6 +369,14 @@ pub mod play {
pub value: f32, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x1e] #[packet_id = 0x1e]
pub struct WorldBorderInitialize { pub struct WorldBorderInitialize {
@ -431,6 +499,17 @@ pub mod play {
pub last_death_location: Option<(Ident<String>, BlockPos)>, pub last_death_location: Option<(Ident<String>, BlockPos)>,
} }
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x26]
pub struct MerchantOffers {
pub window_id: VarInt,
pub trades: Vec<MerchantTrade>,
pub villager_level: VarInt,
pub experience: VarInt,
pub is_regular_villager: bool,
pub can_restock: bool,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x27] #[packet_id = 0x27]
pub struct UpdateEntityPosition { pub struct UpdateEntityPosition {
@ -458,6 +537,20 @@ pub mod play {
pub on_ground: bool, 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x2c] #[packet_id = 0x2c]
pub struct OpenScreen { pub struct OpenScreen {
@ -466,6 +559,25 @@ pub mod play {
pub window_title: Text, 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x30] #[packet_id = 0x30]
pub struct PlayerAbilitiesS2c { pub struct PlayerAbilitiesS2c {
@ -474,6 +586,19 @@ pub mod play {
pub fov_modifier: f32, 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x34] #[packet_id = 0x34]
pub struct CombatDeath { pub struct CombatDeath {
@ -485,7 +610,17 @@ pub mod play {
#[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x35] #[packet_id = 0x35]
pub struct PlayerInfoRemove(pub Vec<Uuid>); pub struct PlayerInfoRemove {
pub players: Vec<Uuid>,
}
#[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<LookAtEntity>,
}
#[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x38] #[packet_id = 0x38]
@ -510,6 +645,13 @@ pub mod play {
pub entity_ids: &'a [VarInt], 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)] #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x3c] #[packet_id = 0x3c]
pub struct ResourcePackS2c<'a> { pub struct ResourcePackS2c<'a> {
@ -571,6 +713,12 @@ pub mod play {
pub blocks: &'a [VarLong], pub blocks: &'a [VarLong],
} }
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x40]
pub struct SelectAdvancementsTab<'a> {
pub identifier: Option<Ident<&'a str>>,
}
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x41] #[packet_id = 0x41]
pub struct ServerData<'a> { pub struct ServerData<'a> {
@ -581,7 +729,47 @@ pub mod play {
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x42] #[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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x49] #[packet_id = 0x49]
@ -598,7 +786,9 @@ pub mod play {
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x4b] #[packet_id = 0x4b]
pub struct SetRenderDistance(pub VarInt); pub struct SetRenderDistance {
pub view_distance: VarInt,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x4c] #[packet_id = 0x4c]
@ -607,6 +797,13 @@ pub mod play {
pub angle: f32, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x4e] #[packet_id = 0x4e]
pub struct SetEntityMetadata<'a> { pub struct SetEntityMetadata<'a> {
@ -614,6 +811,13 @@ pub mod play {
pub metadata: RawBytes<'a>, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x50] #[packet_id = 0x50]
pub struct SetEntityVelocity { pub struct SetEntityVelocity {
@ -637,6 +841,13 @@ pub mod play {
pub food_saturation: f32, 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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x55] #[packet_id = 0x55]
pub struct SetPassengers { pub struct SetPassengers {
@ -645,9 +856,31 @@ pub mod play {
pub passengers: Vec<VarInt>, pub passengers: Vec<VarInt>,
} }
#[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)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x59] #[packet_id = 0x59]
pub struct SetSubtitleText(pub Text); pub struct SetSubtitleText {
pub subtitle_text: Text,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x5a] #[packet_id = 0x5a]
@ -662,7 +895,9 @@ pub mod play {
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x5b] #[packet_id = 0x5b]
pub struct SetTitleText(pub Text); pub struct SetTitleText {
pub title_text: Text,
}
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x5c] #[packet_id = 0x5c]
@ -683,12 +918,13 @@ pub mod play {
pub entity_id: VarInt, pub entity_id: VarInt,
pub volume: f32, pub volume: f32,
pub pitch: f32, pub pitch: f32,
pub seed: i64,
} }
#[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x5e] #[packet_id = 0x5e]
pub struct SoundEffect { pub struct SoundEffect<'a> {
pub id: VarInt, pub id: SoundId<'a>,
pub category: SoundCategory, pub category: SoundCategory,
pub position: [i32; 3], pub position: [i32; 3],
pub volume: f32, pub volume: f32,
@ -700,8 +936,8 @@ pub mod play {
#[packet_id = 0x60] #[packet_id = 0x60]
pub struct SystemChatMessage { pub struct SystemChatMessage {
pub chat: Text, pub chat: Text,
/// Index into the chat type registry. /// Whether the message is in the actionbar or the chat.
pub kind: VarInt, pub overlay: bool,
} }
#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
@ -711,6 +947,13 @@ pub mod play {
pub footer: Text, 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)] #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)]
#[packet_id = 0x63] #[packet_id = 0x63]
pub struct PickupItem { pub struct PickupItem {
@ -742,6 +985,17 @@ pub mod play {
pub features: Vec<Ident<&'a str>>, pub features: Vec<Ident<&'a str>>,
} }
#[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<Compound>,
}
#[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)]
#[packet_id = 0x69] #[packet_id = 0x69]
pub struct DeclareRecipes<'a> { pub struct DeclareRecipes<'a> {
@ -750,7 +1004,9 @@ pub mod play {
#[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)]
#[packet_id = 0x6a] #[packet_id = 0x6a]
pub struct UpdateTags<'a>(pub Vec<TagGroup<'a>>); pub struct UpdateTags<'a> {
pub tags: Vec<TagGroup<'a>>,
}
packet_enum! { packet_enum! {
#[derive(Clone)] #[derive(Clone)]
@ -763,21 +1019,28 @@ pub mod play {
AcknowledgeBlockChange, AcknowledgeBlockChange,
SetBlockDestroyStage, SetBlockDestroyStage,
BlockEntityData, BlockEntityData,
BlockAction,
BlockUpdate, BlockUpdate,
BossBar, BossBar,
SetDifficulty, SetDifficulty,
ClearTitles, ClearTitles,
CommandSuggestionResponse<'a>,
Commands<'a>, Commands<'a>,
CloseContainerS2c, CloseContainerS2c,
SetContainerContent, SetContainerContent,
SetContainerProperty, SetContainerProperty,
SetContainerSlot, SetContainerSlot,
SetCooldown, SetCooldown,
ChatSuggestions<'a>,
PluginMessageS2c<'a>, PluginMessageS2c<'a>,
DeleteMessage<'a>,
DisconnectPlay, DisconnectPlay,
DisguisedChatMessage,
EntityEvent, EntityEvent,
PlaceRecipe<'a>,
UnloadChunk, UnloadChunk,
GameEvent, GameEvent,
OpenHorseScreen,
WorldBorderInitialize, WorldBorderInitialize,
KeepAliveS2c, KeepAliveS2c,
ChunkDataAndUpdateLight<'a>, ChunkDataAndUpdateLight<'a>,
@ -785,47 +1048,74 @@ pub mod play {
UpdateLight, UpdateLight,
ParticleS2c, ParticleS2c,
LoginPlay<'a>, LoginPlay<'a>,
MapData<'a>,
MerchantOffers,
UpdateEntityPosition, UpdateEntityPosition,
UpdateEntityPositionAndRotation, UpdateEntityPositionAndRotation,
UpdateEntityRotation, UpdateEntityRotation,
MoveVehicle,
OpenBook,
OpenScreen, OpenScreen,
OpenSignEditor,
PingPlay,
PlaceGhostRecipe<'a>,
PlayerAbilitiesS2c, PlayerAbilitiesS2c,
PlayerChatMessage<'a>, PlayerChatMessage<'a>,
EndCombat,
EnterCombat,
CombatDeath, CombatDeath,
PlayerInfoRemove, PlayerInfoRemove,
PlayerInfoUpdate<'a>, PlayerInfoUpdate<'a>,
LookAt,
SynchronizePlayerPosition, SynchronizePlayerPosition,
UpdateRecipeBook<'a>, UpdateRecipeBook<'a>,
RemoveEntities, RemoveEntities,
RemoveEntityEffect,
ResourcePackS2c<'a>, ResourcePackS2c<'a>,
Respawn<'a>, Respawn<'a>,
SetHeadRotation, SetHeadRotation,
UpdateSectionBlocks, UpdateSectionBlocks,
SelectAdvancementsTab<'a>,
ServerData<'a>, ServerData<'a>,
SetActionBarText, SetActionBarText,
SetBorderCenter,
SetBorderLerpSize,
SetBorderSize,
SetBorderWarningDelay,
SetBorderWarningDistance,
SetCamera,
SetHeldItemS2c, SetHeldItemS2c,
SetCenterChunk, SetCenterChunk,
SetRenderDistance, SetRenderDistance,
SetDefaultSpawnPosition, SetDefaultSpawnPosition,
DisplayObjective<'a>,
SetEntityMetadata<'a>, SetEntityMetadata<'a>,
LinkEntities,
SetEntityVelocity, SetEntityVelocity,
SetEquipment, SetEquipment,
SetExperience, SetExperience,
SetHealth, SetHealth,
UpdateObjectives<'a>,
SetPassengers, SetPassengers,
UpdateTeams<'a>,
UpdateScore<'a>,
SetSimulationDistance,
SetSubtitleText, SetSubtitleText,
UpdateTime, UpdateTime,
SetTitleText, SetTitleText,
SetTitleAnimationTimes, SetTitleAnimationTimes,
EntitySoundEffect, EntitySoundEffect,
SoundEffect, SoundEffect<'a>,
StopSound<'a>,
SystemChatMessage, SystemChatMessage,
SetTabListHeaderAndFooter, SetTabListHeaderAndFooter,
TagQueryResponse,
PickupItem, PickupItem,
TeleportEntity, TeleportEntity,
UpdateAdvancements<'a>, UpdateAdvancements<'a>,
UpdateAttributes<'a>, UpdateAttributes<'a>,
FeatureFlags<'a>, FeatureFlags<'a>,
EntityEffect,
DeclareRecipes<'a>, DeclareRecipes<'a>,
UpdateTags<'a>, UpdateTags<'a>,
} }

View file

@ -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<Vec<Icon>>,
pub data: Option<Data<'a>>,
}
#[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<Text>,
}
#[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<Self> {
let map_id = VarInt::decode(r)?;
let scale = i8::decode(r)?;
let locked = bool::decode(r)?;
let icons = <Option<Vec<Icon>>>::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,
})
}
}

View file

@ -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<Self> {
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,
})
}
}

View file

@ -1,5 +1,6 @@
use std::io::Write; use std::io::Write;
use crate::packets::s2c::message_signature::MessageSignature;
use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, Uuid, VarInt}; use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, Uuid, VarInt};
#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] #[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)]
@ -8,10 +9,10 @@ pub struct PlayerChatMessage<'a> {
pub sender: Uuid, pub sender: Uuid,
pub index: VarInt, pub index: VarInt,
pub message_signature: Option<&'a [u8; 256]>, pub message_signature: Option<&'a [u8; 256]>,
pub message: String, pub message: &'a str,
pub time_stamp: u64, pub time_stamp: u64,
pub salt: u64, pub salt: u64,
pub previous_messages: Vec<PreviousMessage<'a>>, pub previous_messages: Vec<MessageSignature<'a>>,
pub unsigned_content: Option<Text>, pub unsigned_content: Option<Text>,
pub filter_type: MessageFilterType, pub filter_type: MessageFilterType,
pub filter_type_bits: Option<u8>, pub filter_type_bits: Option<u8>,
@ -20,12 +21,6 @@ pub struct PlayerChatMessage<'a> {
pub network_target_name: Option<Text>, pub network_target_name: Option<Text>,
} }
#[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)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
pub enum MessageFilterType { pub enum MessageFilterType {
PassThrough, PassThrough,
@ -66,10 +61,10 @@ impl<'a> Decode<'a> for PlayerChatMessage<'a> {
let sender = Uuid::decode(r)?; let sender = Uuid::decode(r)?;
let index = VarInt::decode(r)?; let index = VarInt::decode(r)?;
let message_signature = Option::<&'a [u8; 256]>::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 time_stamp = u64::decode(r)?;
let salt = u64::decode(r)?; let salt = u64::decode(r)?;
let previous_messages = Vec::<PreviousMessage>::decode(r)?; let previous_messages = Vec::<MessageSignature>::decode(r)?;
let unsigned_content = Option::<Text>::decode(r)?; let unsigned_content = Option::<Text>::decode(r)?;
let filter_type = MessageFilterType::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<Self> {
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,
})
}
}

View file

@ -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<f32>,
},
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<Self> {
let i = VarInt::decode(r)?.0;
if i == 0 {
Ok(SoundId::Direct {
id: <Ident<&'a str>>::decode(r)?,
range: <Option<f32>>::decode(r)?,
})
} else {
Ok(SoundId::Reference { id: VarInt(i - 1) })
}
}
}

View file

@ -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<SoundCategory>,
pub sound: Option<Ident<&'a str>>,
}
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<Self> {
let (source, sound) = match i8::decode(r)? {
3 => (
Some(SoundCategory::decode(r)?),
Some(<Ident<&'a str>>::decode(r)?),
),
2 => (None, Some(<Ident<&'a str>>::decode(r)?)),
1 => (Some(SoundCategory::decode(r)?), None),
_ => (None, None),
};
Ok(Self { source, sound })
}
}

View file

@ -32,8 +32,8 @@ pub struct AdvancementDisplay<'a> {
pub frame_type: VarInt, pub frame_type: VarInt,
pub flags: i32, pub flags: i32,
pub background_texture: Option<Ident<&'a str>>, pub background_texture: Option<Ident<&'a str>>,
pub x_coord: f64, pub x_coord: f32,
pub y_coord: f64, pub y_coord: f32,
} }
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
@ -78,8 +78,8 @@ impl<'a> Decode<'a> for AdvancementDisplay<'a> {
None None
}; };
let x_coord = f64::decode(r)?; let x_coord = f32::decode(r)?;
let y_coord = f64::decode(r)?; let y_coord = f32::decode(r)?;
Ok(Self { Ok(Self {
title, title,

View file

@ -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<Self> {
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}"),
})
}
}

View file

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use valence_nbt::Compound; 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)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)]
pub enum HandshakeNextState { pub enum HandshakeNextState {
@ -22,22 +22,10 @@ pub struct PublicKeyData<'a> {
pub signature: &'a [u8], pub signature: &'a [u8],
} }
#[derive(Clone, Debug, Encode, Decode)]
pub struct MessageAcknowledgment<'a> {
pub last_seen: Vec<MessageAcknowledgmentEntry<'a>>,
pub last_received: Option<MessageAcknowledgmentEntry<'a>>,
}
#[derive(Copy, Clone, Debug, Encode, Decode)]
pub struct MessageAcknowledgmentEntry<'a> {
pub profile_id: Uuid,
pub signature: &'a [u8],
}
#[derive(Copy, Clone, Debug, Encode, Decode)] #[derive(Copy, Clone, Debug, Encode, Decode)]
pub struct CommandArgumentSignature<'a> { pub struct CommandArgumentSignature<'a> {
pub argument_name: &'a str, pub argument_name: &'a str,
pub signature: &'a [u8], pub signature: &'a [u8; 256],
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)]
@ -377,3 +365,78 @@ pub struct Statistic {
pub statistic_id: VarInt, pub statistic_id: VarInt,
pub value: 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<Text>,
}
#[derive(Clone, PartialEq, Debug, Encode, Decode)]
pub struct MerchantTrade {
pub input_one: Option<ItemStack>,
pub output_item: Option<ItemStack>,
pub input_two: Option<ItemStack>,
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,
}