From 9f5e5c092be9167e4d5222fdee4a1d2c419e5052 Mon Sep 17 00:00:00 2001 From: EightFactorial Date: Tue, 6 Dec 2022 18:48:48 -0800 Subject: Complete ClientboundCommand{Suggestion}sPacket, Serde support for NBT Tags (#49) * Serializing ClientboundStatusResponsePacket Enable serialization of ClientboundStatusResponsePacket * Update clientbound_status_response_packet.rs Add options previewsChat and enforcesSecureChat * Serialize Style and TextColor * Serialize BaseComponent * Serialize TextComponent * Fix Style * Serialize Component * Fix multiple formats per message, fix reset tag * Fix Style, again * Use FlatMapSerializer * Forgot italics * Count struct fields, reorganize logic * Serialize TranslatableComponent * Rewrite TextComponent Serializer * Fix using TextColor::Parse * Code Cleanup * Add default attribute, just in case * Clippy * use serde derive feature + preferred formatting choices * McBufWritable for BrigadierNodeStub * Thanks Clippy... * Implement suggestions in azalea-brigadier * Serde support for NBT Tags * Serde options * Forgot Options * Oops, that's McBufWritable for BrigadierParser * Fix McBufWritable for SlotData * Complete ClientboundUpdateRecipesPacket * fix some issues * better impl McBufReadable for Suggestions Co-authored-by: BuildTools Co-authored-by: mat --- .../src/exceptions/builtin_exceptions.rs | 6 +- .../src/exceptions/command_syntax_exception.rs | 11 ++-- azalea-brigadier/src/lib.rs | 1 - azalea-brigadier/src/message.rs | 14 ---- azalea-brigadier/src/suggestion/mod.rs | 31 +++++++-- azalea-brigadier/src/suggestion/suggestions.rs | 74 +++++++++++++++++++--- 6 files changed, 99 insertions(+), 38 deletions(-) delete mode 100755 azalea-brigadier/src/message.rs (limited to 'azalea-brigadier/src') diff --git a/azalea-brigadier/src/exceptions/builtin_exceptions.rs b/azalea-brigadier/src/exceptions/builtin_exceptions.rs index d95ee237..c3c3c900 100755 --- a/azalea-brigadier/src/exceptions/builtin_exceptions.rs +++ b/azalea-brigadier/src/exceptions/builtin_exceptions.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::{message::Message, string_reader::StringReader}; +use crate::string_reader::StringReader; use super::command_syntax_exception::CommandSyntaxException; @@ -148,12 +148,12 @@ impl fmt::Debug for BuiltInExceptions { impl BuiltInExceptions { pub fn create(self) -> CommandSyntaxException { - let message = Message::from(format!("{self:?}")); + let message = format!("{self:?}"); CommandSyntaxException::create(self, message) } pub fn create_with_context(self, reader: &StringReader) -> CommandSyntaxException { - let message = Message::from(format!("{self:?}")); + let message = format!("{self:?}"); CommandSyntaxException::new(self, message, reader.string(), reader.cursor()) } } diff --git a/azalea-brigadier/src/exceptions/command_syntax_exception.rs b/azalea-brigadier/src/exceptions/command_syntax_exception.rs index 14376a87..0254820d 100755 --- a/azalea-brigadier/src/exceptions/command_syntax_exception.rs +++ b/azalea-brigadier/src/exceptions/command_syntax_exception.rs @@ -1,5 +1,4 @@ use super::builtin_exceptions::BuiltInExceptions; -use crate::message::Message; use std::{ cmp, fmt::{self, Write}, @@ -8,7 +7,7 @@ use std::{ #[derive(Clone, PartialEq)] pub struct CommandSyntaxException { pub type_: BuiltInExceptions, - message: Message, + message: String, input: Option, cursor: Option, } @@ -16,7 +15,7 @@ pub struct CommandSyntaxException { const CONTEXT_AMOUNT: usize = 10; impl CommandSyntaxException { - pub fn new(type_: BuiltInExceptions, message: Message, input: &str, cursor: usize) -> Self { + pub fn new(type_: BuiltInExceptions, message: String, input: &str, cursor: usize) -> Self { Self { type_, message, @@ -25,7 +24,7 @@ impl CommandSyntaxException { } } - pub fn create(type_: BuiltInExceptions, message: Message) -> Self { + pub fn create(type_: BuiltInExceptions, message: String) -> Self { Self { type_, message, @@ -35,7 +34,7 @@ impl CommandSyntaxException { } pub fn message(&self) -> String { - let mut message = self.message.string(); + let mut message = self.message.clone(); let context = self.context(); if let Some(context) = context { write!( @@ -49,7 +48,7 @@ impl CommandSyntaxException { message } - pub fn raw_message(&self) -> &Message { + pub fn raw_message(&self) -> &String { &self.message } diff --git a/azalea-brigadier/src/lib.rs b/azalea-brigadier/src/lib.rs index 3c37b7f3..cf2ce571 100755 --- a/azalea-brigadier/src/lib.rs +++ b/azalea-brigadier/src/lib.rs @@ -3,7 +3,6 @@ pub mod builder; pub mod command_dispatcher; pub mod context; pub mod exceptions; -pub mod message; pub mod modifier; pub mod parse_results; pub mod string_reader; diff --git a/azalea-brigadier/src/message.rs b/azalea-brigadier/src/message.rs deleted file mode 100755 index 75e07d4e..00000000 --- a/azalea-brigadier/src/message.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct Message(String); - -impl Message { - pub fn string(&self) -> String { - self.0.to_string() - } -} - -impl From for Message { - fn from(s: String) -> Self { - Self(s) - } -} diff --git a/azalea-brigadier/src/suggestion/mod.rs b/azalea-brigadier/src/suggestion/mod.rs index 4c9a9547..114a4c47 100755 --- a/azalea-brigadier/src/suggestion/mod.rs +++ b/azalea-brigadier/src/suggestion/mod.rs @@ -1,16 +1,26 @@ mod suggestions; -use crate::{context::StringRange, message::Message}; +use crate::context::StringRange; +#[cfg(feature = "azalea-buf")] +use azalea_buf::McBufWritable; +#[cfg(feature = "azalea-buf")] +use azalea_chat::Component; +#[cfg(feature = "azalea-buf")] +use std::io::Write; pub use suggestions::*; +/// A suggestion given to the user for what they might want to type next. +/// +/// The `M` generic is the type of the tooltip, so for example a `String` or +/// just `()` if you don't care about it. #[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub struct Suggestion { - pub range: StringRange, +pub struct Suggestion { pub text: String, - pub tooltip: Option, + pub range: StringRange, + pub tooltip: Option, } -impl Suggestion { +impl Suggestion { pub fn apply(&self, input: &str) -> String { if self.range.start() == 0 && self.range.end() == input.len() { return input.to_string(); @@ -27,7 +37,7 @@ impl Suggestion { result } - pub fn expand(&self, command: &str, range: &StringRange) -> Suggestion { + pub fn expand(&self, command: &str, range: &StringRange) -> Suggestion { if range == &self.range { return self.clone(); } @@ -46,3 +56,12 @@ impl Suggestion { } } } + +#[cfg(feature = "azalea-buf")] +impl McBufWritable for Suggestion { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + self.text.write_into(buf)?; + self.tooltip.write_into(buf)?; + Ok(()) + } +} diff --git a/azalea-brigadier/src/suggestion/suggestions.rs b/azalea-brigadier/src/suggestion/suggestions.rs index 1fe361f1..06ef9661 100755 --- a/azalea-brigadier/src/suggestion/suggestions.rs +++ b/azalea-brigadier/src/suggestion/suggestions.rs @@ -1,15 +1,23 @@ use super::Suggestion; use crate::context::StringRange; -use std::collections::HashSet; +#[cfg(feature = "azalea-buf")] +use azalea_buf::{ + BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable, +}; +#[cfg(feature = "azalea-buf")] +use azalea_chat::Component; +#[cfg(feature = "azalea-buf")] +use std::io::{Cursor, Write}; +use std::{collections::HashSet, hash::Hash}; -#[derive(Debug, Clone, Default, Eq, PartialEq, Hash)] -pub struct Suggestions { +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub struct Suggestions { pub range: StringRange, - pub suggestions: Vec, + pub suggestions: Vec>, } -impl Suggestions { - pub fn merge(command: &str, input: &[Suggestions]) -> Self { +impl Suggestions { + pub fn merge(command: &str, input: &[Suggestions]) -> Self { if input.is_empty() { return Suggestions::default(); } else if input.len() == 1 { @@ -24,7 +32,7 @@ impl Suggestions { Suggestions::create(command, &texts) } - pub fn create(command: &str, suggestions: &HashSet) -> Self { + pub fn create(command: &str, suggestions: &HashSet>) -> Self { if suggestions.is_empty() { return Suggestions::default(); }; @@ -39,7 +47,7 @@ impl Suggestions { for suggestion in suggestions { texts.insert(suggestion.expand(command, &range)); } - let mut sorted: Vec = texts.into_iter().collect(); + let mut sorted = texts.into_iter().collect::>(); sorted.sort_by(|a, b| a.text.cmp(&b.text)); Suggestions { range, @@ -47,3 +55,53 @@ impl Suggestions { } } } + +// this can't be derived because that'd require the generic to have `Default` +// too even if it's not actually necessary +impl Default for Suggestions { + fn default() -> Self { + Self { + range: StringRange::default(), + suggestions: Vec::new(), + } + } +} + +#[cfg(feature = "azalea-buf")] +impl McBufReadable for Suggestions { + fn read_from(buf: &mut Cursor<&[u8]>) -> Result { + #[derive(McBuf)] + struct StandaloneSuggestion { + pub text: String, + pub tooltip: Option, + } + + let start = u32::var_read_from(buf)? as usize; + let length = u32::var_read_from(buf)? as usize; + let range = StringRange::between(start, start + length); + + // the range of a Suggestion depends on the Suggestions containing it, + // so we can't just `impl McBufReadable for Suggestion` + let mut suggestions = Vec::::read_from(buf)? + .into_iter() + .map(|s| Suggestion { + text: s.text, + tooltip: s.tooltip, + range: range.clone(), + }) + .collect::>(); + suggestions.sort_by(|a, b| a.text.cmp(&b.text)); + + Ok(Suggestions { range, suggestions }) + } +} + +#[cfg(feature = "azalea-buf")] +impl McBufWritable for Suggestions { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + (self.range.start() as u32).var_write_into(buf)?; + (self.range.length() as u32).var_write_into(buf)?; + self.suggestions.write_into(buf)?; + Ok(()) + } +} -- cgit v1.2.3