aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/packets/game/clientbound_commands_packet.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2022-08-20 15:17:07 -0500
committerGitHub <noreply@github.com>2022-08-20 15:17:07 -0500
commitdbb2092ac002790c07ad21cf7d12aabb477a2e74 (patch)
tree5d5bb1e6dbca8250292a9e0b1edc7325699bbbaf /azalea-protocol/src/packets/game/clientbound_commands_packet.rs
parentac4d675d44a93a6625f508263c650206a7ff1f98 (diff)
downloadazalea-drasl-dbb2092ac002790c07ad21cf7d12aabb477a2e74.tar.xz
Implement ALL packets (#16)
* add a couple more packets and improve codegen * enums in packet codegen * fix enums and MORE PACKETS * make unsigned numbers the default * codegen can make hashmaps * UnsizedByteArray in codegen * Vec and Option * enum codgen works in more situations * ServerboundInteractPacket * Fix error with new error system * More packets * more packets * more packets * guess what was added * yeah it's more packets * add more packets * packets * start adding ClientboundBossEventPacket * finish boss event packet * improve codegen for linux * start on command suggestions packet * rename declare_commands to commands * más paquetes * fix generating custom payload packet * more packets * mehr Pakete * improve codegen for movement packets * rename move packets to have "packet" at the end * fix some unused variable warns * addere plus facis * pli da pakoj * plus de paquets * più pacchetti * make ChatFormatting a macro in azalea-chat * change a match to matches! macro * update SetPlayerTeam to use ChatFormatting * ClientboundSetScorePacket & fix clippy warnings * finish game state :tada: * add remaining packets for other states * fix error in ping.rs
Diffstat (limited to 'azalea-protocol/src/packets/game/clientbound_commands_packet.rs')
-rw-r--r--azalea-protocol/src/packets/game/clientbound_commands_packet.rs244
1 files changed, 244 insertions, 0 deletions
diff --git a/azalea-protocol/src/packets/game/clientbound_commands_packet.rs b/azalea-protocol/src/packets/game/clientbound_commands_packet.rs
new file mode 100644
index 00000000..f3ae4ab9
--- /dev/null
+++ b/azalea-protocol/src/packets/game/clientbound_commands_packet.rs
@@ -0,0 +1,244 @@
+use azalea_buf::BufReadError;
+use azalea_buf::McBuf;
+use azalea_buf::McBufVarReadable;
+use azalea_buf::{McBufReadable, McBufWritable, Readable, Writable};
+use azalea_core::ResourceLocation;
+use packet_macros::ClientboundGamePacket;
+use std::{
+ hash::Hash,
+ io::{Read, Write},
+};
+
+#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
+pub struct ClientboundCommandsPacket {
+ pub entries: Vec<BrigadierNodeStub>,
+ #[var]
+ pub root_index: i32,
+}
+
+#[derive(Hash, Debug, Clone)]
+pub struct BrigadierNodeStub {}
+
+#[derive(Debug, Clone)]
+pub struct BrigadierNumber<T> {
+ min: Option<T>,
+ max: Option<T>,
+}
+impl<T: McBufReadable> McBufReadable for BrigadierNumber<T> {
+ fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> {
+ let flags = buf.read_byte()?;
+ let min = if flags & 0x01 != 0 {
+ Some(T::read_from(buf)?)
+ } else {
+ None
+ };
+ let max = if flags & 0x02 != 0 {
+ Some(T::read_from(buf)?)
+ } else {
+ None
+ };
+ Ok(BrigadierNumber { min, max })
+ }
+}
+impl<T: McBufWritable> McBufWritable for BrigadierNumber<T> {
+ fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
+ let mut flags = 0;
+ if self.min.is_some() {
+ flags |= 0x01;
+ }
+ if self.max.is_some() {
+ flags |= 0x02;
+ }
+ buf.write_byte(flags)?;
+ if let Some(min) = &self.min {
+ min.write_into(buf)?;
+ }
+ if let Some(max) = &self.max {
+ max.write_into(buf)?;
+ }
+ Ok(())
+ }
+}
+
+#[derive(Debug, Clone, Copy, McBuf)]
+pub enum BrigadierString {
+ /// Reads a single word
+ SingleWord = 0,
+ // If it starts with a ", keeps reading until another " (allowing escaping with \). Otherwise behaves the same as SINGLE_WORD
+ QuotablePhrase = 1,
+ // Reads the rest of the content after the cursor. Quotes will not be removed.
+ GreedyPhrase = 2,
+}
+
+#[derive(Debug, Clone)]
+pub enum BrigadierParser {
+ Bool,
+ Double(BrigadierNumber<f64>),
+ Float(BrigadierNumber<f32>),
+ Integer(BrigadierNumber<i32>),
+ Long(BrigadierNumber<i64>),
+ String(BrigadierString),
+ Entity { single: bool, players_only: bool },
+ GameProfile,
+ BlockPos,
+ ColumnPos,
+ Vec3,
+ Vec2,
+ BlockState,
+ BlockPredicate,
+ ItemStack,
+ ItemPredicate,
+ Color,
+ Component,
+ Message,
+ Nbt,
+ NbtPath,
+ Objective,
+ ObjectiveCriteira,
+ Operation,
+ Particle,
+ Rotation,
+ Angle,
+ ScoreboardSlot,
+ ScoreHolder { allows_multiple: bool },
+ Swizzle,
+ Team,
+ ItemSlot,
+ ResourceLocation,
+ MobEffect,
+ Function,
+ EntityAnchor,
+ IntRange,
+ FloatRange,
+ ItemEnchantment,
+ EntitySummon,
+ Dimension,
+ Uuid,
+ NbtTag,
+ NbtCompoundTag,
+ Time,
+ ResourceOrTag { registry_key: ResourceLocation },
+ Resource { registry_key: ResourceLocation },
+ TemplateMirror,
+ TemplateRotation,
+}
+
+impl McBufReadable for BrigadierParser {
+ fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> {
+ let parser_type = u32::var_read_from(buf)?;
+
+ match parser_type {
+ 0 => Ok(BrigadierParser::Bool),
+ 1 => Ok(BrigadierParser::Float(BrigadierNumber::read_from(buf)?)),
+ 2 => Ok(BrigadierParser::Double(BrigadierNumber::read_from(buf)?)),
+ 3 => Ok(BrigadierParser::Integer(BrigadierNumber::read_from(buf)?)),
+ 4 => Ok(BrigadierParser::Long(BrigadierNumber::read_from(buf)?)),
+ 5 => Ok(BrigadierParser::String(BrigadierString::read_from(buf)?)),
+ 6 => {
+ let flags = buf.read_byte()?;
+ Ok(BrigadierParser::Entity {
+ single: flags & 0x01 != 0,
+ players_only: flags & 0x02 != 0,
+ })
+ }
+ 7 => Ok(BrigadierParser::GameProfile),
+ 8 => Ok(BrigadierParser::BlockPos),
+ 9 => Ok(BrigadierParser::ColumnPos),
+ 10 => Ok(BrigadierParser::Vec3),
+ 11 => Ok(BrigadierParser::Vec2),
+ 12 => Ok(BrigadierParser::BlockState),
+ 13 => Ok(BrigadierParser::BlockPredicate),
+ 14 => Ok(BrigadierParser::ItemStack),
+ 15 => Ok(BrigadierParser::ItemPredicate),
+ 16 => Ok(BrigadierParser::Color),
+ 17 => Ok(BrigadierParser::Component),
+ 18 => Ok(BrigadierParser::Message),
+ 19 => Ok(BrigadierParser::NbtCompoundTag),
+ 20 => Ok(BrigadierParser::NbtTag),
+ 21 => Ok(BrigadierParser::NbtPath),
+ 22 => Ok(BrigadierParser::Objective),
+ 23 => Ok(BrigadierParser::ObjectiveCriteira),
+ 24 => Ok(BrigadierParser::Operation),
+ 25 => Ok(BrigadierParser::Particle),
+ 26 => Ok(BrigadierParser::Angle),
+ 27 => Ok(BrigadierParser::Rotation),
+ 28 => Ok(BrigadierParser::ScoreboardSlot),
+ 29 => {
+ let flags = buf.read_byte()?;
+ Ok(BrigadierParser::ScoreHolder {
+ allows_multiple: flags & 0x01 != 0,
+ })
+ }
+ 30 => Ok(BrigadierParser::Swizzle),
+ 31 => Ok(BrigadierParser::Team),
+ 32 => Ok(BrigadierParser::ItemSlot),
+ 33 => Ok(BrigadierParser::ResourceLocation),
+ 34 => Ok(BrigadierParser::MobEffect),
+ 35 => Ok(BrigadierParser::Function),
+ 36 => Ok(BrigadierParser::EntityAnchor),
+ 37 => Ok(BrigadierParser::IntRange),
+ 38 => Ok(BrigadierParser::FloatRange),
+ 39 => Ok(BrigadierParser::ItemEnchantment),
+ 40 => Ok(BrigadierParser::EntitySummon),
+ 41 => Ok(BrigadierParser::Dimension),
+ 42 => Ok(BrigadierParser::Time),
+ 43 => Ok(BrigadierParser::ResourceOrTag {
+ registry_key: ResourceLocation::read_from(buf)?,
+ }),
+ 44 => Ok(BrigadierParser::Resource {
+ registry_key: ResourceLocation::read_from(buf)?,
+ }),
+ 45 => Ok(BrigadierParser::TemplateMirror),
+ 46 => Ok(BrigadierParser::TemplateRotation),
+ 47 => Ok(BrigadierParser::Uuid),
+ _ => Err(BufReadError::UnexpectedEnumVariant {
+ id: parser_type as i32,
+ }),
+ }
+ }
+}
+
+// TODO: BrigadierNodeStub should have more stuff
+impl McBufReadable for BrigadierNodeStub {
+ fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> {
+ let flags = u8::read_from(buf)?;
+ if flags > 31 {
+ println!(
+ "Warning: The flags from a Brigadier node are over 31 ({flags}; {flags:#b}). This is probably a bug.",
+ );
+ }
+
+ let node_type = flags & 0x03;
+ let _is_executable = flags & 0x04 != 0;
+ let has_redirect = flags & 0x08 != 0;
+ let has_suggestions_type = flags & 0x10 != 0;
+
+ let _children = buf.read_int_id_list()?;
+ let _redirect_node = if has_redirect { buf.read_varint()? } else { 0 };
+
+ // argument node
+ if node_type == 2 {
+ let _name = buf.read_utf()?;
+ let _parser = BrigadierParser::read_from(buf)?;
+ let _suggestions_type = if has_suggestions_type {
+ Some(ResourceLocation::read_from(buf)?)
+ } else {
+ None
+ };
+ return Ok(BrigadierNodeStub {});
+ }
+ // literal node
+ if node_type == 1 {
+ let _name = buf.read_utf()?;
+ return Ok(BrigadierNodeStub {});
+ }
+ Ok(BrigadierNodeStub {})
+ // return Err("Unknown node type".to_string());
+ }
+}
+
+impl McBufWritable for BrigadierNodeStub {
+ fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> {
+ todo!()
+ }
+}