mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
rename Component to FormattedText
also start making the metadata use bevy_ecs but bevy_ecs doesn't let you query on Bundles so it's annoying
This commit is contained in:
parent
129e2adf0a
commit
52772afe85
42 changed files with 11094 additions and 10584 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -295,6 +295,7 @@ dependencies = [
|
||||||
"azalea-buf",
|
"azalea-buf",
|
||||||
"azalea-chat",
|
"azalea-chat",
|
||||||
"azalea-nbt",
|
"azalea-nbt",
|
||||||
|
"bevy_ecs",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::context::StringRange;
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
use azalea_buf::McBufWritable;
|
use azalea_buf::McBufWritable;
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
pub use suggestions::*;
|
pub use suggestions::*;
|
||||||
|
@ -58,7 +58,7 @@ impl<M: Clone> Suggestion<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
impl McBufWritable for Suggestion<Component> {
|
impl McBufWritable for Suggestion<FormattedText> {
|
||||||
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
||||||
self.text.write_into(buf)?;
|
self.text.write_into(buf)?;
|
||||||
self.tooltip.write_into(buf)?;
|
self.tooltip.write_into(buf)?;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use azalea_buf::{
|
||||||
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
use std::{collections::HashSet, hash::Hash};
|
use std::{collections::HashSet, hash::Hash};
|
||||||
|
@ -68,12 +68,12 @@ impl<M> Default for Suggestions<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
impl McBufReadable for Suggestions<Component> {
|
impl McBufReadable for Suggestions<FormattedText> {
|
||||||
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||||
#[derive(McBuf)]
|
#[derive(McBuf)]
|
||||||
struct StandaloneSuggestion {
|
struct StandaloneSuggestion {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub tooltip: Option<Component>,
|
pub tooltip: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = u32::var_read_from(buf)? as usize;
|
let start = u32::var_read_from(buf)? as usize;
|
||||||
|
@ -97,7 +97,7 @@ impl McBufReadable for Suggestions<Component> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "azalea-buf")]
|
#[cfg(feature = "azalea-buf")]
|
||||||
impl McBufWritable for Suggestions<Component> {
|
impl McBufWritable for Suggestions<FormattedText> {
|
||||||
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
||||||
(self.range.start() as u32).var_write_into(buf)?;
|
(self.range.start() as u32).var_write_into(buf)?;
|
||||||
(self.range.length() as u32).var_write_into(buf)?;
|
(self.range.length() as u32).var_write_into(buf)?;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::{style::Style, Component};
|
use crate::{style::Style, FormattedText};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||||
pub struct BaseComponent {
|
pub struct BaseComponent {
|
||||||
// implements mutablecomponent
|
// implements mutablecomponent
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
pub siblings: Vec<Component>,
|
pub siblings: Vec<FormattedText>,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub style: Style,
|
pub style: Style,
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use std::{
|
||||||
/// A chat component, basically anything you can see in chat.
|
/// A chat component, basically anything you can see in chat.
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Component {
|
pub enum FormattedText {
|
||||||
Text(TextComponent),
|
Text(TextComponent),
|
||||||
Translatable(TranslatableComponent),
|
Translatable(TranslatableComponent),
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ pub static DEFAULT_STYLE: Lazy<Style> = Lazy::new(|| Style {
|
||||||
});
|
});
|
||||||
|
|
||||||
/// A chat component
|
/// A chat component
|
||||||
impl Component {
|
impl FormattedText {
|
||||||
pub fn get_base_mut(&mut self) -> &mut BaseComponent {
|
pub fn get_base_mut(&mut self) -> &mut BaseComponent {
|
||||||
match self {
|
match self {
|
||||||
Self::Text(c) => &mut c.base,
|
Self::Text(c) => &mut c.base,
|
||||||
|
@ -43,14 +43,16 @@ impl Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a component as a sibling of this one
|
/// Add a component as a sibling of this one
|
||||||
fn append(&mut self, sibling: Component) {
|
fn append(&mut self, sibling: FormattedText) {
|
||||||
self.get_base_mut().siblings.push(sibling);
|
self.get_base_mut().siblings.push(sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the "separator" component from the json
|
/// Get the "separator" component from the json
|
||||||
fn parse_separator(json: &serde_json::Value) -> Result<Option<Component>, serde_json::Error> {
|
fn parse_separator(
|
||||||
|
json: &serde_json::Value,
|
||||||
|
) -> Result<Option<FormattedText>, serde_json::Error> {
|
||||||
if json.get("separator").is_some() {
|
if json.get("separator").is_some() {
|
||||||
return Ok(Some(Component::deserialize(
|
return Ok(Some(FormattedText::deserialize(
|
||||||
json.get("separator").unwrap(),
|
json.get("separator").unwrap(),
|
||||||
)?));
|
)?));
|
||||||
}
|
}
|
||||||
|
@ -61,16 +63,17 @@ impl Component {
|
||||||
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code), so you
|
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code), so you
|
||||||
/// can print it to your terminal and get styling.
|
/// can print it to your terminal and get styling.
|
||||||
///
|
///
|
||||||
/// This is technically a shortcut for [`Component::to_ansi_custom_style`]
|
/// This is technically a shortcut for
|
||||||
/// with a default [`Style`] colored white.
|
/// [`FormattedText::to_ansi_custom_style`] with a default [`Style`]
|
||||||
|
/// colored white.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use azalea_chat::Component;
|
/// use azalea_chat::FormattedText;
|
||||||
/// use serde::de::Deserialize;
|
/// use serde::de::Deserialize;
|
||||||
///
|
///
|
||||||
/// let component = Component::deserialize(&serde_json::json!({
|
/// let component = FormattedText::deserialize(&serde_json::json!({
|
||||||
/// "text": "Hello, world!",
|
/// "text": "Hello, world!",
|
||||||
/// "color": "red",
|
/// "color": "red",
|
||||||
/// })).unwrap();
|
/// })).unwrap();
|
||||||
|
@ -85,7 +88,7 @@ impl Component {
|
||||||
/// Convert this component into an
|
/// Convert this component into an
|
||||||
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code).
|
/// [ANSI string](https://en.wikipedia.org/wiki/ANSI_escape_code).
|
||||||
///
|
///
|
||||||
/// This is the same as [`Component::to_ansi`], but you can specify a
|
/// This is the same as [`FormattedText::to_ansi`], but you can specify a
|
||||||
/// default [`Style`] to use.
|
/// default [`Style`] to use.
|
||||||
pub fn to_ansi_custom_style(&self, default_style: &Style) -> String {
|
pub fn to_ansi_custom_style(&self, default_style: &Style) -> String {
|
||||||
// this contains the final string will all the ansi escape codes
|
// this contains the final string will all the ansi escape codes
|
||||||
|
@ -116,12 +119,12 @@ impl Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for Component {
|
impl IntoIterator for FormattedText {
|
||||||
/// Recursively call the function for every component in this component
|
/// Recursively call the function for every component in this component
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
let base = self.get_base();
|
let base = self.get_base();
|
||||||
let siblings = base.siblings.clone();
|
let siblings = base.siblings.clone();
|
||||||
let mut v: Vec<Component> = Vec::with_capacity(siblings.len() + 1);
|
let mut v: Vec<FormattedText> = Vec::with_capacity(siblings.len() + 1);
|
||||||
v.push(self);
|
v.push(self);
|
||||||
for sibling in siblings {
|
for sibling in siblings {
|
||||||
v.extend(sibling.into_iter());
|
v.extend(sibling.into_iter());
|
||||||
|
@ -130,11 +133,11 @@ impl IntoIterator for Component {
|
||||||
v.into_iter()
|
v.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Item = Component;
|
type Item = FormattedText;
|
||||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Component {
|
impl<'de> Deserialize<'de> for FormattedText {
|
||||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
|
@ -142,11 +145,11 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
let json: serde_json::Value = serde::Deserialize::deserialize(de)?;
|
let json: serde_json::Value = serde::Deserialize::deserialize(de)?;
|
||||||
|
|
||||||
// we create a component that we might add siblings to
|
// we create a component that we might add siblings to
|
||||||
let mut component: Component;
|
let mut component: FormattedText;
|
||||||
|
|
||||||
// if it's primitive, make it a text component
|
// if it's primitive, make it a text component
|
||||||
if !json.is_array() && !json.is_object() {
|
if !json.is_array() && !json.is_object() {
|
||||||
return Ok(Component::Text(TextComponent::new(
|
return Ok(FormattedText::Text(TextComponent::new(
|
||||||
json.as_str().unwrap_or("").to_string(),
|
json.as_str().unwrap_or("").to_string(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -154,7 +157,7 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
else if json.is_object() {
|
else if json.is_object() {
|
||||||
if let Some(text) = json.get("text") {
|
if let Some(text) = json.get("text") {
|
||||||
let text = text.as_str().unwrap_or("").to_string();
|
let text = text.as_str().unwrap_or("").to_string();
|
||||||
component = Component::Text(TextComponent::new(text));
|
component = FormattedText::Text(TextComponent::new(text));
|
||||||
} else if let Some(translate) = json.get("translate") {
|
} else if let Some(translate) = json.get("translate") {
|
||||||
let translate = translate
|
let translate = translate
|
||||||
.as_str()
|
.as_str()
|
||||||
|
@ -169,8 +172,8 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
// if it's a string component with no styling and no siblings, just add a
|
// if it's a string component with no styling and no siblings, just add a
|
||||||
// string to with_array otherwise add the component
|
// string to with_array otherwise add the component
|
||||||
// to the array
|
// to the array
|
||||||
let c = Component::deserialize(item).map_err(de::Error::custom)?;
|
let c = FormattedText::deserialize(item).map_err(de::Error::custom)?;
|
||||||
if let Component::Text(text_component) = c {
|
if let FormattedText::Text(text_component) = c {
|
||||||
if text_component.base.siblings.is_empty()
|
if text_component.base.siblings.is_empty()
|
||||||
&& text_component.base.style.is_empty()
|
&& text_component.base.style.is_empty()
|
||||||
{
|
{
|
||||||
|
@ -178,16 +181,19 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
with_array.push(StringOrComponent::Component(
|
with_array.push(StringOrComponent::FormattedText(
|
||||||
Component::deserialize(item).map_err(de::Error::custom)?,
|
FormattedText::deserialize(item).map_err(de::Error::custom)?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
component =
|
component = FormattedText::Translatable(TranslatableComponent::new(
|
||||||
Component::Translatable(TranslatableComponent::new(translate, with_array));
|
translate, with_array,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
// if it doesn't have a "with", just have the with_array be empty
|
// if it doesn't have a "with", just have the with_array be empty
|
||||||
component =
|
component = FormattedText::Translatable(TranslatableComponent::new(
|
||||||
Component::Translatable(TranslatableComponent::new(translate, Vec::new()));
|
translate,
|
||||||
|
Vec::new(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else if let Some(score) = json.get("score") {
|
} else if let Some(score) = json.get("score") {
|
||||||
// object = GsonHelper.getAsJsonObject(jsonObject, "score");
|
// object = GsonHelper.getAsJsonObject(jsonObject, "score");
|
||||||
|
@ -213,10 +219,11 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
nbt
|
nbt
|
||||||
} else {
|
} else {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
format!("Don't know how to turn {json} into a Component").as_str(),
|
format!("Don't know how to turn {json} into a FormattedText").as_str(),
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
let _separator = Component::parse_separator(&json).map_err(de::Error::custom)?;
|
let _separator =
|
||||||
|
FormattedText::parse_separator(&json).map_err(de::Error::custom)?;
|
||||||
|
|
||||||
let _interpret = match json.get("interpret") {
|
let _interpret = match json.get("interpret") {
|
||||||
Some(v) => v.as_bool().ok_or(Some(false)).unwrap(),
|
Some(v) => v.as_bool().ok_or(Some(false)).unwrap(),
|
||||||
|
@ -237,7 +244,7 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
}
|
}
|
||||||
for extra_component in extra {
|
for extra_component in extra {
|
||||||
let sibling =
|
let sibling =
|
||||||
Component::deserialize(extra_component).map_err(de::Error::custom)?;
|
FormattedText::deserialize(extra_component).map_err(de::Error::custom)?;
|
||||||
component.append(sibling);
|
component.append(sibling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,33 +257,35 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
// ok so it's not an object, if it's an array deserialize every item
|
// ok so it's not an object, if it's an array deserialize every item
|
||||||
else if !json.is_array() {
|
else if !json.is_array() {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
format!("Don't know how to turn {json} into a Component").as_str(),
|
format!("Don't know how to turn {json} into a FormattedText").as_str(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let json_array = json.as_array().unwrap();
|
let json_array = json.as_array().unwrap();
|
||||||
// the first item in the array is the one that we're gonna return, the others
|
// the first item in the array is the one that we're gonna return, the others
|
||||||
// are siblings
|
// are siblings
|
||||||
let mut component = Component::deserialize(&json_array[0]).map_err(de::Error::custom)?;
|
let mut component =
|
||||||
|
FormattedText::deserialize(&json_array[0]).map_err(de::Error::custom)?;
|
||||||
for i in 1..json_array.len() {
|
for i in 1..json_array.len() {
|
||||||
component.append(
|
component.append(
|
||||||
Component::deserialize(json_array.get(i).unwrap()).map_err(de::Error::custom)?,
|
FormattedText::deserialize(json_array.get(i).unwrap())
|
||||||
|
.map_err(de::Error::custom)?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(component)
|
Ok(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McBufReadable for Component {
|
impl McBufReadable for FormattedText {
|
||||||
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||||
let string = String::read_from(buf)?;
|
let string = String::read_from(buf)?;
|
||||||
debug!("Component string: {}", string);
|
debug!("FormattedText string: {}", string);
|
||||||
let json: serde_json::Value = serde_json::from_str(string.as_str())?;
|
let json: serde_json::Value = serde_json::from_str(string.as_str())?;
|
||||||
let component = Component::deserialize(json)?;
|
let component = FormattedText::deserialize(json)?;
|
||||||
Ok(component)
|
Ok(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McBufWritable for Component {
|
impl McBufWritable for FormattedText {
|
||||||
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
||||||
let json = serde_json::to_string(self).unwrap();
|
let json = serde_json::to_string(self).unwrap();
|
||||||
json.write_into(buf)?;
|
json.write_into(buf)?;
|
||||||
|
@ -284,31 +293,31 @@ impl McBufWritable for Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Component {
|
impl From<String> for FormattedText {
|
||||||
fn from(s: String) -> Self {
|
fn from(s: String) -> Self {
|
||||||
Component::Text(TextComponent {
|
FormattedText::Text(TextComponent {
|
||||||
text: s,
|
text: s,
|
||||||
base: BaseComponent::default(),
|
base: BaseComponent::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<&str> for Component {
|
impl From<&str> for FormattedText {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
Self::from(s.to_string())
|
Self::from(s.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Component {
|
impl Display for FormattedText {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Component::Text(c) => c.fmt(f),
|
FormattedText::Text(c) => c.fmt(f),
|
||||||
Component::Translatable(c) => c.fmt(f),
|
FormattedText::Translatable(c) => c.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Component {
|
impl Default for FormattedText {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Component::Text(TextComponent::default())
|
FormattedText::Text(TextComponent::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,4 @@ pub mod style;
|
||||||
pub mod text_component;
|
pub mod text_component;
|
||||||
pub mod translatable_component;
|
pub mod translatable_component;
|
||||||
|
|
||||||
pub use component::Component;
|
pub use component::FormattedText;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{base_component::BaseComponent, style::ChatFormatting, Component};
|
use crate::{base_component::BaseComponent, style::ChatFormatting, FormattedText};
|
||||||
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer};
|
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ impl Serialize for TextComponent {
|
||||||
|
|
||||||
const LEGACY_FORMATTING_CODE_SYMBOL: char = '§';
|
const LEGACY_FORMATTING_CODE_SYMBOL: char = '§';
|
||||||
|
|
||||||
/// Convert a legacy color code string into a Component
|
/// Convert a legacy color code string into a FormattedText
|
||||||
/// Technically in Minecraft this is done when displaying the text, but AFAIK
|
/// Technically in Minecraft this is done when displaying the text, but AFAIK
|
||||||
/// it's the same as just doing it in TextComponent
|
/// it's the same as just doing it in TextComponent
|
||||||
pub fn legacy_color_code_to_text_component(legacy_color_code: &str) -> TextComponent {
|
pub fn legacy_color_code_to_text_component(legacy_color_code: &str) -> TextComponent {
|
||||||
|
@ -98,18 +98,18 @@ impl TextComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(self) -> Component {
|
fn get(self) -> FormattedText {
|
||||||
Component::Text(self)
|
FormattedText::Text(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for TextComponent {
|
impl Display for TextComponent {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// this contains the final string will all the ansi escape codes
|
// this contains the final string will all the ansi escape codes
|
||||||
for component in Component::Text(self.clone()).into_iter() {
|
for component in FormattedText::Text(self.clone()).into_iter() {
|
||||||
let component_text = match &component {
|
let component_text = match &component {
|
||||||
Component::Text(c) => c.text.to_string(),
|
FormattedText::Text(c) => c.text.to_string(),
|
||||||
Component::Translatable(c) => c.read()?.to_string(),
|
FormattedText::Translatable(c) => c.read()?.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
f.write_str(&component_text)?;
|
f.write_str(&component_text)?;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
base_component::BaseComponent, style::Style, text_component::TextComponent, Component,
|
base_component::BaseComponent, style::Style, text_component::TextComponent, FormattedText,
|
||||||
};
|
};
|
||||||
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer};
|
use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSerializer};
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use serde::{ser::SerializeMap, Serialize, Serializer, __private::ser::FlatMapSer
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum StringOrComponent {
|
pub enum StringOrComponent {
|
||||||
String(String),
|
String(String),
|
||||||
Component(Component),
|
FormattedText(FormattedText),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A message whose content depends on the client's language.
|
/// A message whose content depends on the client's language.
|
||||||
|
@ -42,7 +42,7 @@ impl TranslatableComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the key and args to a Component.
|
/// Convert the key and args to a FormattedText.
|
||||||
pub fn read(&self) -> Result<TextComponent, fmt::Error> {
|
pub fn read(&self) -> Result<TextComponent, fmt::Error> {
|
||||||
let template = azalea_language::get(&self.key).unwrap_or(&self.key);
|
let template = azalea_language::get(&self.key).unwrap_or(&self.key);
|
||||||
// decode the % things
|
// decode the % things
|
||||||
|
@ -122,7 +122,7 @@ impl TranslatableComponent {
|
||||||
|
|
||||||
Ok(TextComponent {
|
Ok(TextComponent {
|
||||||
base: BaseComponent {
|
base: BaseComponent {
|
||||||
siblings: components.into_iter().map(Component::Text).collect(),
|
siblings: components.into_iter().map(FormattedText::Text).collect(),
|
||||||
style: Style::default(),
|
style: Style::default(),
|
||||||
},
|
},
|
||||||
text: "".to_string(),
|
text: "".to_string(),
|
||||||
|
@ -133,10 +133,10 @@ impl TranslatableComponent {
|
||||||
impl Display for TranslatableComponent {
|
impl Display for TranslatableComponent {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// this contains the final string will all the ansi escape codes
|
// this contains the final string will all the ansi escape codes
|
||||||
for component in Component::Translatable(self.clone()).into_iter() {
|
for component in FormattedText::Translatable(self.clone()).into_iter() {
|
||||||
let component_text = match &component {
|
let component_text = match &component {
|
||||||
Component::Text(c) => c.text.to_string(),
|
FormattedText::Text(c) => c.text.to_string(),
|
||||||
Component::Translatable(c) => c.read()?.to_string(),
|
FormattedText::Translatable(c) => c.read()?.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
f.write_str(&component_text)?;
|
f.write_str(&component_text)?;
|
||||||
|
@ -150,7 +150,7 @@ impl Display for StringOrComponent {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
StringOrComponent::String(s) => write!(f, "{s}"),
|
StringOrComponent::String(s) => write!(f, "{s}"),
|
||||||
StringOrComponent::Component(c) => write!(f, "{c}"),
|
StringOrComponent::FormattedText(c) => write!(f, "{c}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ impl From<StringOrComponent> for TextComponent {
|
||||||
fn from(soc: StringOrComponent) -> Self {
|
fn from(soc: StringOrComponent) -> Self {
|
||||||
match soc {
|
match soc {
|
||||||
StringOrComponent::String(s) => TextComponent::new(s),
|
StringOrComponent::String(s) => TextComponent::new(s),
|
||||||
StringOrComponent::Component(c) => TextComponent::new(c.to_string()),
|
StringOrComponent::FormattedText(c) => TextComponent::new(c.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use azalea_chat::{
|
use azalea_chat::{
|
||||||
style::{Ansi, ChatFormatting, TextColor},
|
style::{Ansi, ChatFormatting, TextColor},
|
||||||
Component,
|
FormattedText,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
@ -15,7 +15,7 @@ fn basic_ansi_test() {
|
||||||
}"#,
|
}"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let component = Component::deserialize(&j).unwrap();
|
let component = FormattedText::deserialize(&j).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
component.to_ansi(),
|
component.to_ansi(),
|
||||||
"\u{1b}[1m\u{1b}[38;2;255;85;85mhello\u{1b}[m"
|
"\u{1b}[1m\u{1b}[38;2;255;85;85mhello\u{1b}[m"
|
||||||
|
@ -51,7 +51,7 @@ fn complex_ansi_test() {
|
||||||
]"##,
|
]"##,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let component = Component::deserialize(&j).unwrap();
|
let component = FormattedText::deserialize(&j).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
component.to_ansi(),
|
component.to_ansi(),
|
||||||
format!(
|
format!(
|
||||||
|
@ -70,6 +70,6 @@ fn complex_ansi_test() {
|
||||||
#[test]
|
#[test]
|
||||||
fn component_from_string() {
|
fn component_from_string() {
|
||||||
let j: Value = serde_json::from_str("\"foo\"").unwrap();
|
let j: Value = serde_json::from_str("\"foo\"").unwrap();
|
||||||
let component = Component::deserialize(&j).unwrap();
|
let component = FormattedText::deserialize(&j).unwrap();
|
||||||
assert_eq!(component.to_ansi(), "foo");
|
assert_eq!(component.to_ansi(), "foo");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Implementations of chat-related features.
|
//! Implementations of chat-related features.
|
||||||
|
|
||||||
use crate::Client;
|
use crate::Client;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol::packets::game::{
|
use azalea_protocol::packets::game::{
|
||||||
clientbound_player_chat_packet::ClientboundPlayerChatPacket,
|
clientbound_player_chat_packet::ClientboundPlayerChatPacket,
|
||||||
clientbound_system_chat_packet::ClientboundSystemChatPacket,
|
clientbound_system_chat_packet::ClientboundSystemChatPacket,
|
||||||
|
@ -29,7 +29,7 @@ macro_rules! regex {
|
||||||
|
|
||||||
impl ChatPacket {
|
impl ChatPacket {
|
||||||
/// Get the message shown in chat for this packet.
|
/// Get the message shown in chat for this packet.
|
||||||
pub fn message(&self) -> Component {
|
pub fn message(&self) -> FormattedText {
|
||||||
match self {
|
match self {
|
||||||
ChatPacket::System(p) => p.content.clone(),
|
ChatPacket::System(p) => p.content.clone(),
|
||||||
ChatPacket::Player(p) => p.message(),
|
ChatPacket::Player(p) => p.message(),
|
||||||
|
@ -83,7 +83,7 @@ impl ChatPacket {
|
||||||
/// convenience function for testing.
|
/// convenience function for testing.
|
||||||
pub fn new(message: &str) -> Self {
|
pub fn new(message: &str) -> Self {
|
||||||
ChatPacket::System(Arc::new(ClientboundSystemChatPacket {
|
ChatPacket::System(Arc::new(ClientboundSystemChatPacket {
|
||||||
content: Component::from(message),
|
content: FormattedText::from(message),
|
||||||
overlay: false,
|
overlay: false,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_auth::game_profile::GameProfile;
|
use azalea_auth::game_profile::GameProfile;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_core::GameType;
|
use azalea_core::GameType;
|
||||||
use azalea_world::PartialWorld;
|
use azalea_world::PartialWorld;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -13,5 +13,5 @@ pub struct PlayerInfo {
|
||||||
pub gamemode: GameType,
|
pub gamemode: GameType,
|
||||||
pub latency: i32,
|
pub latency: i32,
|
||||||
/// The player's display name in the tab list.
|
/// The player's display name in the tab list.
|
||||||
pub display_name: Option<Component>,
|
pub display_name: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,17 @@ description = "Miscellaneous things in Azalea."
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "azalea-core"
|
name = "azalea-core"
|
||||||
version = "0.5.0"
|
|
||||||
repository = "https://github.com/mat-1/azalea/tree/main/azalea-core"
|
repository = "https://github.com/mat-1/azalea/tree/main/azalea-core"
|
||||||
|
version = "0.5.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
azalea-buf = {path = "../azalea-buf", version = "^0.5.0" }
|
azalea-buf = {path = "../azalea-buf", version = "^0.5.0"}
|
||||||
azalea-chat = {path = "../azalea-chat", version = "^0.5.0" }
|
azalea-chat = {path = "../azalea-chat", version = "^0.5.0"}
|
||||||
azalea-nbt = {path = "../azalea-nbt", version = "^0.5.0" }
|
azalea-nbt = {path = "../azalea-nbt", version = "^0.5.0"}
|
||||||
|
bevy_ecs = {version = "0.9.1", default-features = false, optional = true}
|
||||||
uuid = "^1.1.2"
|
uuid = "^1.1.2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
bevy_ecs = ["dep:bevy_ecs"]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{BlockPos, Slot};
|
use crate::{BlockPos, Slot};
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "bevy_ecs", derive(bevy_ecs::component::Component))]
|
||||||
#[derive(Debug, Clone, McBuf, Default)]
|
#[derive(Debug, Clone, McBuf, Default)]
|
||||||
pub struct Particle {
|
pub struct Particle {
|
||||||
#[var]
|
#[var]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use azalea_buf::{
|
use azalea_buf::{
|
||||||
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
||||||
};
|
};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -18,7 +18,7 @@ pub enum Operation {
|
||||||
Add(AddOperation),
|
Add(AddOperation),
|
||||||
Remove,
|
Remove,
|
||||||
UpdateProgress(f32),
|
UpdateProgress(f32),
|
||||||
UpdateName(Component),
|
UpdateName(FormattedText),
|
||||||
UpdateStyle(Style),
|
UpdateStyle(Style),
|
||||||
UpdateProperties(Properties),
|
UpdateProperties(Properties),
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ impl McBufReadable for Operation {
|
||||||
0 => Operation::Add(AddOperation::read_from(buf)?),
|
0 => Operation::Add(AddOperation::read_from(buf)?),
|
||||||
1 => Operation::Remove,
|
1 => Operation::Remove,
|
||||||
2 => Operation::UpdateProgress(f32::read_from(buf)?),
|
2 => Operation::UpdateProgress(f32::read_from(buf)?),
|
||||||
3 => Operation::UpdateName(Component::read_from(buf)?),
|
3 => Operation::UpdateName(FormattedText::read_from(buf)?),
|
||||||
4 => Operation::UpdateStyle(Style::read_from(buf)?),
|
4 => Operation::UpdateStyle(Style::read_from(buf)?),
|
||||||
5 => Operation::UpdateProperties(Properties::read_from(buf)?),
|
5 => Operation::UpdateProperties(Properties::read_from(buf)?),
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -75,7 +75,7 @@ impl McBufWritable for Operation {
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf)]
|
#[derive(Clone, Debug, McBuf)]
|
||||||
pub struct AddOperation {
|
pub struct AddOperation {
|
||||||
name: Component,
|
name: FormattedText,
|
||||||
progress: f32,
|
progress: f32,
|
||||||
style: Style,
|
style: Style,
|
||||||
properties: Properties,
|
properties: Properties,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundChatPreviewPacket {
|
pub struct ClientboundChatPreviewPacket {
|
||||||
pub query_id: i32,
|
pub query_id: i32,
|
||||||
pub preview: Option<Component>,
|
pub preview: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use azalea_brigadier::suggestion::Suggestions;
|
use azalea_brigadier::suggestion::Suggestions;
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundCommandSuggestionsPacket {
|
pub struct ClientboundCommandSuggestionsPacket {
|
||||||
#[var]
|
#[var]
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
pub suggestions: Suggestions<Component>,
|
pub suggestions: Suggestions<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -24,7 +24,7 @@ mod tests {
|
||||||
suggestions: vec![Suggestion {
|
suggestions: vec![Suggestion {
|
||||||
text: "foo".to_string(),
|
text: "foo".to_string(),
|
||||||
range: StringRange::new(1, 4),
|
range: StringRange::new(1, 4),
|
||||||
tooltip: Some(Component::from("bar".to_string())),
|
tooltip: Some(FormattedText::from("bar".to_string())),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub enum BrigadierParser {
|
||||||
ItemStack,
|
ItemStack,
|
||||||
ItemPredicate,
|
ItemPredicate,
|
||||||
Color,
|
Color,
|
||||||
Component,
|
FormattedText,
|
||||||
Message,
|
Message,
|
||||||
NbtCompoundTag,
|
NbtCompoundTag,
|
||||||
NbtTag,
|
NbtTag,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundDisconnectPacket {
|
pub struct ClientboundDisconnectPacket {
|
||||||
pub reason: Component,
|
pub reason: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use super::clientbound_player_chat_packet::ChatTypeBound;
|
use super::clientbound_player_chat_packet::ChatTypeBound;
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundDisguisedChatPacket {
|
pub struct ClientboundDisguisedChatPacket {
|
||||||
pub message: Component,
|
pub message: FormattedText,
|
||||||
pub chat_type: ChatTypeBound,
|
pub chat_type: ChatTypeBound,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use azalea_buf::{BufReadError, McBuf};
|
use azalea_buf::{BufReadError, McBuf};
|
||||||
use azalea_buf::{McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
|
use azalea_buf::{McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ pub struct MapDecoration {
|
||||||
/// Minecraft does & 15 on this value, azalea-protocol doesn't. I don't
|
/// Minecraft does & 15 on this value, azalea-protocol doesn't. I don't
|
||||||
/// think it matters.
|
/// think it matters.
|
||||||
pub rot: i8,
|
pub rot: i8,
|
||||||
pub name: Option<Component>,
|
pub name: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
|
@ -7,5 +7,5 @@ pub struct ClientboundOpenScreenPacket {
|
||||||
#[var]
|
#[var]
|
||||||
pub container_id: u32,
|
pub container_id: u32,
|
||||||
pub menu_type: azalea_registry::Menu,
|
pub menu_type: azalea_registry::Menu,
|
||||||
pub title: Component,
|
pub title: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use azalea_buf::{
|
||||||
};
|
};
|
||||||
use azalea_chat::{
|
use azalea_chat::{
|
||||||
translatable_component::{StringOrComponent, TranslatableComponent},
|
translatable_component::{StringOrComponent, TranslatableComponent},
|
||||||
Component,
|
FormattedText,
|
||||||
};
|
};
|
||||||
use azalea_core::BitSet;
|
use azalea_core::BitSet;
|
||||||
use azalea_crypto::MessageSignature;
|
use azalea_crypto::MessageSignature;
|
||||||
|
@ -18,7 +18,7 @@ pub struct ClientboundPlayerChatPacket {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub signature: Option<MessageSignature>,
|
pub signature: Option<MessageSignature>,
|
||||||
pub body: PackedSignedMessageBody,
|
pub body: PackedSignedMessageBody,
|
||||||
pub unsigned_content: Option<Component>,
|
pub unsigned_content: Option<FormattedText>,
|
||||||
pub filter_mask: FilterMask,
|
pub filter_mask: FilterMask,
|
||||||
pub chat_type: ChatTypeBound,
|
pub chat_type: ChatTypeBound,
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,8 @@ pub enum ChatType {
|
||||||
#[derive(Clone, Debug, McBuf, PartialEq)]
|
#[derive(Clone, Debug, McBuf, PartialEq)]
|
||||||
pub struct ChatTypeBound {
|
pub struct ChatTypeBound {
|
||||||
pub chat_type: ChatType,
|
pub chat_type: ChatType,
|
||||||
pub name: Component,
|
pub name: FormattedText,
|
||||||
pub target_name: Option<Component>,
|
pub target_name: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be in Client
|
// must be in Client
|
||||||
|
@ -87,17 +87,17 @@ pub struct MessageSignatureCache {
|
||||||
// {} }
|
// {} }
|
||||||
|
|
||||||
impl ClientboundPlayerChatPacket {
|
impl ClientboundPlayerChatPacket {
|
||||||
/// Returns the content of the message. If you want to get the Component
|
/// Returns the content of the message. If you want to get the FormattedText
|
||||||
/// for the whole message including the sender part, use
|
/// for the whole message including the sender part, use
|
||||||
/// [`ClientboundPlayerChatPacket::message`].
|
/// [`ClientboundPlayerChatPacket::message`].
|
||||||
pub fn content(&self) -> Component {
|
pub fn content(&self) -> FormattedText {
|
||||||
self.unsigned_content
|
self.unsigned_content
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| Component::from(self.body.content.clone()))
|
.unwrap_or_else(|| FormattedText::from(self.body.content.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the full message, including the sender part.
|
/// Get the full message, including the sender part.
|
||||||
pub fn message(&self) -> Component {
|
pub fn message(&self) -> FormattedText {
|
||||||
let sender = self.chat_type.name.clone();
|
let sender = self.chat_type.name.clone();
|
||||||
let content = self.content();
|
let content = self.content();
|
||||||
let target = self.chat_type.target_name.clone();
|
let target = self.chat_type.target_name.clone();
|
||||||
|
@ -105,16 +105,16 @@ impl ClientboundPlayerChatPacket {
|
||||||
let translation_key = self.chat_type.chat_type.chat_translation_key();
|
let translation_key = self.chat_type.chat_type.chat_translation_key();
|
||||||
|
|
||||||
let mut args = vec![
|
let mut args = vec![
|
||||||
StringOrComponent::Component(sender),
|
StringOrComponent::FormattedText(sender),
|
||||||
StringOrComponent::Component(content),
|
StringOrComponent::FormattedText(content),
|
||||||
];
|
];
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
args.push(StringOrComponent::Component(target));
|
args.push(StringOrComponent::FormattedText(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
let component = TranslatableComponent::new(translation_key.to_string(), args);
|
let component = TranslatableComponent::new(translation_key.to_string(), args);
|
||||||
|
|
||||||
Component::Translatable(component)
|
FormattedText::Translatable(component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
/// Used to send a respawn screen.
|
/// Used to send a respawn screen.
|
||||||
|
@ -8,5 +8,5 @@ pub struct ClientboundPlayerCombatKillPacket {
|
||||||
#[var]
|
#[var]
|
||||||
pub player_id: u32,
|
pub player_id: u32,
|
||||||
pub killer_id: u32,
|
pub killer_id: u32,
|
||||||
pub message: Component,
|
pub message: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use azalea_auth::game_profile::{GameProfile, ProfilePropertyValue};
|
||||||
use azalea_buf::{
|
use azalea_buf::{
|
||||||
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
|
||||||
};
|
};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_core::{BitSet, GameType};
|
use azalea_core::{BitSet, GameType};
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -25,7 +25,7 @@ pub struct PlayerInfoEntry {
|
||||||
pub listed: bool,
|
pub listed: bool,
|
||||||
pub latency: i32,
|
pub latency: i32,
|
||||||
pub game_mode: GameType,
|
pub game_mode: GameType,
|
||||||
pub display_name: Option<Component>,
|
pub display_name: Option<FormattedText>,
|
||||||
pub chat_session: Option<RemoteChatSessionData>,
|
pub chat_session: Option<RemoteChatSessionData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub struct UpdateLatencyAction {
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug, McBuf)]
|
#[derive(Clone, Debug, McBuf)]
|
||||||
pub struct UpdateDisplayNameAction {
|
pub struct UpdateDisplayNameAction {
|
||||||
pub display_name: Option<Component>,
|
pub display_name: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McBufReadable for ClientboundPlayerInfoUpdatePacket {
|
impl McBufReadable for ClientboundPlayerInfoUpdatePacket {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
|
@ -7,5 +7,5 @@ pub struct ClientboundResourcePackPacket {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
pub required: bool,
|
pub required: bool,
|
||||||
pub prompt: Option<Component>,
|
pub prompt: Option<FormattedText>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundServerDataPacket {
|
pub struct ClientboundServerDataPacket {
|
||||||
pub motd: Option<Component>,
|
pub motd: Option<FormattedText>,
|
||||||
pub icon_base64: Option<String>,
|
pub icon_base64: Option<String>,
|
||||||
pub enforces_secure_chat: bool,
|
pub enforces_secure_chat: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundSetActionBarTextPacket {
|
pub struct ClientboundSetActionBarTextPacket {
|
||||||
pub text: Component,
|
pub text: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
|
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ impl McBufWritable for Method {
|
||||||
|
|
||||||
#[derive(McBuf, Clone, Debug)]
|
#[derive(McBuf, Clone, Debug)]
|
||||||
pub struct DisplayInfo {
|
pub struct DisplayInfo {
|
||||||
pub display_name: Component,
|
pub display_name: FormattedText,
|
||||||
pub render_type: RenderType,
|
pub render_type: RenderType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
|
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
|
||||||
use azalea_chat::{style::ChatFormatting, Component};
|
use azalea_chat::{style::ChatFormatting, FormattedText};
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
|
@ -61,13 +61,13 @@ impl McBufWritable for Method {
|
||||||
|
|
||||||
#[derive(McBuf, Clone, Debug)]
|
#[derive(McBuf, Clone, Debug)]
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub display_name: Component,
|
pub display_name: FormattedText,
|
||||||
pub options: u8,
|
pub options: u8,
|
||||||
pub nametag_visibility: String,
|
pub nametag_visibility: String,
|
||||||
pub collision_rule: String,
|
pub collision_rule: String,
|
||||||
pub color: ChatFormatting,
|
pub color: ChatFormatting,
|
||||||
pub player_prefix: Component,
|
pub player_prefix: FormattedText,
|
||||||
pub player_suffix: Component,
|
pub player_suffix: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlayerList = Vec<String>;
|
type PlayerList = Vec<String>;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundSetSubtitleTextPacket {
|
pub struct ClientboundSetSubtitleTextPacket {
|
||||||
pub text: Component,
|
pub text: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundSetTitleTextPacket {
|
pub struct ClientboundSetTitleTextPacket {
|
||||||
pub text: Component,
|
pub text: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket, PartialEq)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket, PartialEq)]
|
||||||
pub struct ClientboundSystemChatPacket {
|
pub struct ClientboundSystemChatPacket {
|
||||||
pub content: Component,
|
pub content: FormattedText,
|
||||||
pub overlay: bool,
|
pub overlay: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundTabListPacket {
|
pub struct ClientboundTabListPacket {
|
||||||
pub header: Component,
|
pub header: FormattedText,
|
||||||
pub footer: Component,
|
pub footer: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_core::{ResourceLocation, Slot};
|
use azalea_core::{ResourceLocation, Slot};
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -25,8 +25,8 @@ pub struct Advancement {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisplayInfo {
|
pub struct DisplayInfo {
|
||||||
pub title: Component,
|
pub title: FormattedText,
|
||||||
pub description: Component,
|
pub description: FormattedText,
|
||||||
pub icon: Slot,
|
pub icon: Slot,
|
||||||
pub frame: FrameType,
|
pub frame: FrameType,
|
||||||
pub show_toast: bool,
|
pub show_toast: bool,
|
||||||
|
@ -132,9 +132,9 @@ pub struct CriterionProgress {
|
||||||
// Advancement {
|
// Advancement {
|
||||||
// parent_id: None,
|
// parent_id: None,
|
||||||
// display: Some(DisplayInfo {
|
// display: Some(DisplayInfo {
|
||||||
// title: Component::from("title".to_string()),
|
// title: FormattedText::from("title".to_string()),
|
||||||
// description:
|
// description:
|
||||||
// Component::from("description".to_string()), icon:
|
// FormattedText::from("description".to_string()), icon:
|
||||||
// Slot::Empty, frame: FrameType::Task,
|
// Slot::Empty, frame: FrameType::Task,
|
||||||
// show_toast: true,
|
// show_toast: true,
|
||||||
// hidden: false,
|
// hidden: false,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use azalea_buf::McBuf;
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundLoginPacket;
|
use azalea_protocol_macros::ClientboundLoginPacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundLoginPacket)]
|
||||||
pub struct ClientboundLoginDisconnectPacket {
|
pub struct ClientboundLoginDisconnectPacket {
|
||||||
pub reason: Component,
|
pub reason: FormattedText,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
|
use azalea_buf::{BufReadError, McBufReadable, McBufWritable};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_protocol_macros::ClientboundStatusPacket;
|
use azalea_protocol_macros::ClientboundStatusPacket;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{value::Serializer, Value};
|
use serde_json::{value::Serializer, Value};
|
||||||
|
@ -28,7 +28,7 @@ pub struct Players {
|
||||||
// the entire packet is just json, which is why it has deserialize
|
// the entire packet is just json, which is why it has deserialize
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, ClientboundStatusPacket)]
|
#[derive(Clone, Debug, Serialize, Deserialize, ClientboundStatusPacket)]
|
||||||
pub struct ClientboundStatusResponsePacket {
|
pub struct ClientboundStatusResponsePacket {
|
||||||
pub description: Component,
|
pub description: FormattedText,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub favicon: Option<String>,
|
pub favicon: Option<String>,
|
||||||
|
|
|
@ -1205,7 +1205,7 @@ registry!(CommandArgumentKind, {
|
||||||
ItemStack => "minecraft:item_stack",
|
ItemStack => "minecraft:item_stack",
|
||||||
ItemPredicate => "minecraft:item_predicate",
|
ItemPredicate => "minecraft:item_predicate",
|
||||||
Color => "minecraft:color",
|
Color => "minecraft:color",
|
||||||
Component => "minecraft:component",
|
FormattedText => "minecraft:component",
|
||||||
Message => "minecraft:message",
|
Message => "minecraft:message",
|
||||||
NbtCompoundTag => "minecraft:nbt_compound_tag",
|
NbtCompoundTag => "minecraft:nbt_compound_tag",
|
||||||
NbtTag => "minecraft:nbt_tag",
|
NbtTag => "minecraft:nbt_tag",
|
||||||
|
|
|
@ -9,13 +9,13 @@ version = "0.5.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
azalea-block = { path = "../azalea-block", default-features = false, version = "^0.5.0" }
|
azalea-block = {path = "../azalea-block", default-features = false, version = "^0.5.0"}
|
||||||
azalea-buf = { path = "../azalea-buf", version = "^0.5.0" }
|
azalea-buf = {path = "../azalea-buf", version = "^0.5.0"}
|
||||||
azalea-chat = { path = "../azalea-chat", version = "^0.5.0" }
|
azalea-chat = {path = "../azalea-chat", version = "^0.5.0"}
|
||||||
azalea-core = { path = "../azalea-core", version = "^0.5.0" }
|
azalea-core = {path = "../azalea-core", version = "^0.5.0", features = ["bevy_ecs"]}
|
||||||
azalea-nbt = { path = "../azalea-nbt", version = "^0.5.0" }
|
azalea-nbt = {path = "../azalea-nbt", version = "^0.5.0"}
|
||||||
azalea-registry = { path = "../azalea-registry", version = "^0.5.0" }
|
azalea-registry = {path = "../azalea-registry", version = "^0.5.0"}
|
||||||
bevy_ecs = { version = "0.9.1", default-features = false }
|
bevy_ecs = {version = "0.9.1", default-features = false}
|
||||||
enum-as-inner = "0.5.1"
|
enum-as-inner = "0.5.1"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
nohash-hasher = "0.2.0"
|
nohash-hasher = "0.2.0"
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use azalea_block::BlockState;
|
use azalea_block::BlockState;
|
||||||
use azalea_buf::{BufReadError, McBufVarReadable, McBufVarWritable};
|
use azalea_buf::{BufReadError, McBufVarReadable, McBufVarWritable};
|
||||||
use azalea_buf::{McBuf, McBufReadable, McBufWritable};
|
use azalea_buf::{McBuf, McBufReadable, McBufWritable};
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_core::{BlockPos, Direction, GlobalPos, Particle, Slot};
|
use azalea_core::{BlockPos, Direction, GlobalPos, Particle, Slot};
|
||||||
|
use bevy_ecs::component::Component;
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
use nohash_hasher::IntSet;
|
use nohash_hasher::IntSet;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
|
@ -52,8 +53,8 @@ pub enum EntityDataValue {
|
||||||
Long(i64),
|
Long(i64),
|
||||||
Float(f32),
|
Float(f32),
|
||||||
String(String),
|
String(String),
|
||||||
Component(Component),
|
FormattedText(FormattedText),
|
||||||
OptionalComponent(Option<Component>),
|
OptionalComponent(Option<FormattedText>),
|
||||||
ItemStack(Slot),
|
ItemStack(Slot),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Rotations(Rotations),
|
Rotations(Rotations),
|
||||||
|
@ -105,7 +106,7 @@ pub struct Rotations {
|
||||||
pub z: f32,
|
pub z: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy, McBuf, Default)]
|
#[derive(Clone, Debug, Copy, McBuf, Default, Component)]
|
||||||
pub enum Pose {
|
pub enum Pose {
|
||||||
#[default]
|
#[default]
|
||||||
Standing = 0,
|
Standing = 0,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,8 +15,8 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
|
||||||
{'name': 'Long', 'type': 'i64'},
|
{'name': 'Long', 'type': 'i64'},
|
||||||
{'name': 'Float', 'type': 'f32'},
|
{'name': 'Float', 'type': 'f32'},
|
||||||
{'name': 'String', 'type': 'String'},
|
{'name': 'String', 'type': 'String'},
|
||||||
{'name': 'Component', 'type': 'Component'},
|
{'name': 'Component', 'type': 'FormattedText'},
|
||||||
{'name': 'OptionalComponent', 'type': 'Option<Component>'},
|
{'name': 'OptionalComponent', 'type': 'Option<FormattedText>'},
|
||||||
{'name': 'ItemStack', 'type': 'Slot'},
|
{'name': 'ItemStack', 'type': 'Slot'},
|
||||||
{'name': 'Boolean', 'type': 'bool'},
|
{'name': 'Boolean', 'type': 'bool'},
|
||||||
{'name': 'Rotations', 'type': 'Rotations'},
|
{'name': 'Rotations', 'type': 'Rotations'},
|
||||||
|
@ -45,9 +45,9 @@ use super::{
|
||||||
EntityDataValue, EntityMetadataItems, OptionalUnsignedInt, Pose, Rotations, VillagerData,
|
EntityDataValue, EntityMetadataItems, OptionalUnsignedInt, Pose, Rotations, VillagerData,
|
||||||
};
|
};
|
||||||
use azalea_block::BlockState;
|
use azalea_block::BlockState;
|
||||||
use azalea_chat::Component;
|
use azalea_chat::FormattedText;
|
||||||
use azalea_core::{BlockPos, Direction, Particle, Slot};
|
use azalea_core::{BlockPos, Direction, Particle, Slot};
|
||||||
use hecs::{Query, EntityBuilder, BuiltEntity};
|
use bevy_ecs::{bundle::Bundle, component::Component};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -160,33 +160,124 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
metadata_type_data = metadata_types[type_id]
|
metadata_type_data = metadata_types[type_id]
|
||||||
rust_type = metadata_type_data['type']
|
rust_type = metadata_type_data['type']
|
||||||
|
|
||||||
|
code.append(f'#[derive(Component)]')
|
||||||
code.append(f'pub struct {struct_name}(pub {rust_type});')
|
code.append(f'pub struct {struct_name}(pub {rust_type});')
|
||||||
else:
|
else:
|
||||||
# if it's a bitfield just make a struct for each bit
|
# if it's a bitfield just make a struct for each bit
|
||||||
for mask, name in name_or_bitfield.items():
|
for mask, name in name_or_bitfield.items():
|
||||||
name = maybe_rename_field(name, index)
|
name = maybe_rename_field(name, index)
|
||||||
struct_name = upper_first_letter(to_camel_case(name))
|
struct_name = upper_first_letter(to_camel_case(name))
|
||||||
|
code.append(f'#[derive(Component)]')
|
||||||
code.append(f'pub struct {struct_name}(pub bool);')
|
code.append(f'pub struct {struct_name}(pub bool);')
|
||||||
|
|
||||||
# add the entity struct and Query struct
|
# add the entity struct and Query struct
|
||||||
is_actually_entity = not entity_id.startswith('~')
|
is_actually_entity = not entity_id.startswith('~')
|
||||||
if is_actually_entity:
|
if is_actually_entity:
|
||||||
struct_name: str = upper_first_letter(to_camel_case(entity_id))
|
struct_name: str = upper_first_letter(to_camel_case(entity_id))
|
||||||
|
code.append(f'#[derive(Component)]')
|
||||||
code.append(f'pub struct {struct_name};')
|
code.append(f'pub struct {struct_name};')
|
||||||
|
|
||||||
# impl Allay {
|
# #[derive(Bundle)]
|
||||||
# pub fn default(builder: &mut EntityBuilder) {
|
# struct AllayBundle {
|
||||||
# builder
|
# health: Health,
|
||||||
# .add(OnFire(false))
|
# ...
|
||||||
# .add(ShiftKeyDown(false))
|
# dancing: Dancing,
|
||||||
# .add(Sprinting(false))
|
# can_duplicate: CanDuplicate,
|
||||||
# .add(Swimming(false));
|
# }
|
||||||
|
bundle_struct_name = f'{struct_name}Bundle'
|
||||||
|
code.append(f'')
|
||||||
|
code.append(f'#[derive(Bundle)]')
|
||||||
|
code.append(f'struct {bundle_struct_name} {{')
|
||||||
|
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
||||||
|
if isinstance(name_or_bitfield, str):
|
||||||
|
name_or_bitfield = maybe_rename_field(
|
||||||
|
name_or_bitfield, index)
|
||||||
|
struct_name = upper_first_letter(
|
||||||
|
to_camel_case(name_or_bitfield))
|
||||||
|
code.append(
|
||||||
|
f' {name_or_bitfield}: {struct_name},')
|
||||||
|
else:
|
||||||
|
for mask, name in name_or_bitfield.items():
|
||||||
|
name = maybe_rename_field(name, index)
|
||||||
|
|
||||||
|
struct_name = upper_first_letter(to_camel_case(name))
|
||||||
|
code.append(f' {name}: {struct_name},')
|
||||||
|
code.append('}')
|
||||||
|
|
||||||
|
# impl AllayBundle {
|
||||||
|
# pub fn update_metadata(
|
||||||
|
# &mut self,
|
||||||
|
# ecs: bevy_ecs::world::World,
|
||||||
|
# entity: bevy_ecs::world::EntityMut,
|
||||||
|
# data: EntityMetadataItems,
|
||||||
|
# ) -> Result<(), UpdateMetadataError> {
|
||||||
|
# for d in data.0 {
|
||||||
|
# match d.index {
|
||||||
|
# 0 => self.health = Health(d.value.into_float()?),
|
||||||
|
# 1 => self.dancing = Dancing(d.value.into_boolean()?),
|
||||||
|
# 2 => self.can_duplicate = CanDuplicate(d.value.into_boolean()?),
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
code.append(f'impl {struct_name} {{')
|
code.append(f'impl {bundle_struct_name} {{')
|
||||||
code.append(
|
code.append(
|
||||||
' pub fn default(builder: &mut EntityBuilder) -> BuiltEntity {')
|
f' pub fn update_metadata(&mut self, ecs: bevy_ecs::world::World, entity: bevy_ecs::world::EntityMut, data: EntityMetadataItems) -> Result<(), UpdateMetadataError> {{')
|
||||||
code.append(' builder')
|
code.append(f' for d in data.0 {{')
|
||||||
|
code.append(f' match d.index {{')
|
||||||
|
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
||||||
|
if isinstance(name_or_bitfield, str):
|
||||||
|
name_or_bitfield = maybe_rename_field(
|
||||||
|
name_or_bitfield, index)
|
||||||
|
|
||||||
|
struct_name = upper_first_letter(
|
||||||
|
to_camel_case(name_or_bitfield))
|
||||||
|
if name_or_bitfield in single_use_imported_types:
|
||||||
|
struct_name = ''
|
||||||
|
|
||||||
|
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
|
||||||
|
'type_id']
|
||||||
|
metadata_type_data = metadata_types[type_id]
|
||||||
|
rust_type = metadata_type_data['type']
|
||||||
|
type_name = metadata_type_data['name']
|
||||||
|
|
||||||
|
type_name_field = to_snake_case(type_name)
|
||||||
|
read_field_code = f'{struct_name}(d.value.into_{type_name_field}()?)' if struct_name else f'd.value.into_{type_name_field}()?'
|
||||||
|
code.append(
|
||||||
|
f' {index} => self.{name_or_bitfield} = {read_field_code},')
|
||||||
|
else:
|
||||||
|
code.append(f' {index} => {{')
|
||||||
|
code.append(
|
||||||
|
f'let bitfield = d.value.into_byte()?;')
|
||||||
|
for mask, name in name_or_bitfield.items():
|
||||||
|
name = maybe_rename_field(name, index)
|
||||||
|
struct_name = upper_first_letter(to_camel_case(name))
|
||||||
|
|
||||||
|
code.append(
|
||||||
|
f'self.{name} = {struct_name}(bitfield & {mask} != 0);')
|
||||||
|
code.append(' },')
|
||||||
|
code.append(' }')
|
||||||
|
code.append(' }')
|
||||||
|
code.append(' Ok(())')
|
||||||
|
code.append(' }')
|
||||||
|
code.append('}')
|
||||||
|
code.append('')
|
||||||
|
|
||||||
|
# impl Default for AllayBundle {
|
||||||
|
# fn default() -> Self {
|
||||||
|
# Self {
|
||||||
|
# on_fire: OnFire(false),
|
||||||
|
# shift_key_down: ShiftKeyDown(false),
|
||||||
|
# sprinting: Sprinting(false),
|
||||||
|
# swimming: Swimming(false)
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
code.append(f'impl Default for {bundle_struct_name} {{')
|
||||||
|
code.append(
|
||||||
|
' fn default() -> Self {')
|
||||||
|
code.append(' Self {')
|
||||||
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
||||||
default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get(
|
default = next(filter(lambda i: i['index'] == index, entity_metadatas)).get(
|
||||||
'default', 'Default::default()')
|
'default', 'Default::default()')
|
||||||
|
@ -212,7 +303,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
elif type_name == 'FrogVariant':
|
elif type_name == 'FrogVariant':
|
||||||
default = 'azalea_registry::FrogVariant::Temperate'
|
default = 'azalea_registry::FrogVariant::Temperate'
|
||||||
elif type_name == 'VillagerData':
|
elif type_name == 'VillagerData':
|
||||||
default = 'VillagerData { kind: azalea_registry::VillagerType::Plains, profession: azalea_registry::VillagerProfession::None, level: 0 }'
|
default = 'VillagerData { kind: azalea_registry::VillagerKind::Plains, profession: azalea_registry::VillagerProfession::None, level: 0 }'
|
||||||
else:
|
else:
|
||||||
default = f'{type_name}::default()' if name in single_use_imported_types else 'Default::default()'
|
default = f'{type_name}::default()' if name in single_use_imported_types else 'Default::default()'
|
||||||
else:
|
else:
|
||||||
|
@ -238,10 +329,10 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
elif type_name == 'CompoundTag':
|
elif type_name == 'CompoundTag':
|
||||||
default = f'azalea_nbt::Tag::Compound({default})' if default != 'Empty' else 'azalea_nbt::Tag::Compound(Default::default())'
|
default = f'azalea_nbt::Tag::Compound({default})' if default != 'Empty' else 'azalea_nbt::Tag::Compound(Default::default())'
|
||||||
if name in single_use_imported_types:
|
if name in single_use_imported_types:
|
||||||
code.append(f' .add({default})')
|
code.append(f' {name}: {default},')
|
||||||
else:
|
else:
|
||||||
code.append(
|
code.append(
|
||||||
f' .add({upper_first_letter(to_camel_case(name))}({default}))')
|
f' {name}: {upper_first_letter(to_camel_case(name))}({default}),')
|
||||||
else:
|
else:
|
||||||
# if it's a bitfield, we'll have to extract the default for
|
# if it's a bitfield, we'll have to extract the default for
|
||||||
# each bool from each bit in the default
|
# each bool from each bit in the default
|
||||||
|
@ -251,94 +342,8 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
bit_default = 'true' if (
|
bit_default = 'true' if (
|
||||||
default & mask != 0) else 'false'
|
default & mask != 0) else 'false'
|
||||||
code.append(
|
code.append(
|
||||||
f' .add({upper_first_letter(to_camel_case(name))}({bit_default}))')
|
f' {name}: {upper_first_letter(to_camel_case(name))}({bit_default}),')
|
||||||
code.append(f' .build()')
|
|
||||||
code.append(' }')
|
|
||||||
code.append('}')
|
|
||||||
|
|
||||||
# #[derive(Query)]
|
|
||||||
# struct AllayQuery<'a> {
|
|
||||||
# health: &'a mut Health,
|
|
||||||
# ...
|
|
||||||
# dancing: &'a mut Dancing,
|
|
||||||
# can_duplicate: &'a mut CanDuplicate,
|
|
||||||
# }
|
|
||||||
query_struct_name = f'{struct_name}Query'
|
|
||||||
code.append(f'')
|
|
||||||
code.append(f'#[derive(Query)]')
|
|
||||||
code.append(f'struct {query_struct_name}<\'a> {{')
|
|
||||||
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
|
||||||
if isinstance(name_or_bitfield, str):
|
|
||||||
name_or_bitfield = maybe_rename_field(
|
|
||||||
name_or_bitfield, index)
|
|
||||||
struct_name = upper_first_letter(
|
|
||||||
to_camel_case(name_or_bitfield))
|
|
||||||
code.append(
|
|
||||||
f' {name_or_bitfield}: &\'a mut {struct_name},')
|
|
||||||
else:
|
|
||||||
for mask, name in name_or_bitfield.items():
|
|
||||||
name = maybe_rename_field(name, index)
|
|
||||||
|
|
||||||
struct_name = upper_first_letter(to_camel_case(name))
|
|
||||||
code.append(f' {name}: &\'a mut {struct_name},')
|
|
||||||
code.append('}')
|
|
||||||
|
|
||||||
# impl AllayQuery<'_> {
|
|
||||||
# pub fn update_metadata(
|
|
||||||
# &mut self,
|
|
||||||
# world: hecs::World,
|
|
||||||
# entity: hecs::Entity,
|
|
||||||
# data: EntityMetadataItems,
|
|
||||||
# ) -> Result<(), UpdateMetadataError> {
|
|
||||||
# for d in data.0 {
|
|
||||||
# match d.index {
|
|
||||||
# 0 => *self.health = Health(d.value.into_float()?),
|
|
||||||
# 1 => *self.dancing = Dancing(d.value.into_boolean()?),
|
|
||||||
# 2 => *self.can_duplicate = CanDuplicate(d.value.into_boolean()?),
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# Ok(())
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
code.append(f'impl {query_struct_name}<\'_> {{')
|
|
||||||
code.append(
|
|
||||||
f' pub fn update_metadata(&mut self, world: hecs::World, entity: hecs::Entity, data: EntityMetadataItems) -> Result<(), UpdateMetadataError> {{')
|
|
||||||
code.append(f' for d in data.0 {{')
|
|
||||||
code.append(f' match d.index {{')
|
|
||||||
for index, name_or_bitfield in enumerate(all_field_names_or_bitfields):
|
|
||||||
if isinstance(name_or_bitfield, str):
|
|
||||||
name_or_bitfield = maybe_rename_field(
|
|
||||||
name_or_bitfield, index)
|
|
||||||
|
|
||||||
struct_name = upper_first_letter(
|
|
||||||
to_camel_case(name_or_bitfield))
|
|
||||||
if name_or_bitfield in single_use_imported_types:
|
|
||||||
struct_name = ''
|
|
||||||
|
|
||||||
type_id = next(filter(lambda i: i['index'] == index, entity_metadatas))[
|
|
||||||
'type_id']
|
|
||||||
metadata_type_data = metadata_types[type_id]
|
|
||||||
rust_type = metadata_type_data['type']
|
|
||||||
type_name = metadata_type_data['name']
|
|
||||||
|
|
||||||
type_name_field = to_snake_case(type_name)
|
|
||||||
read_field_code = f'{struct_name}(d.value.into_{type_name_field}()?)' if struct_name else f'd.value.into_{type_name_field}()?'
|
|
||||||
code.append(
|
|
||||||
f' {index} => *self.{name_or_bitfield} = {read_field_code},')
|
|
||||||
else:
|
|
||||||
code.append(f' {index} => {{')
|
|
||||||
code.append(
|
|
||||||
f'let bitfield = d.value.into_byte()?;')
|
|
||||||
for mask, name in name_or_bitfield.items():
|
|
||||||
name = maybe_rename_field(name, index)
|
|
||||||
struct_name = upper_first_letter(to_camel_case(name))
|
|
||||||
|
|
||||||
code.append(
|
|
||||||
f'*self.{name} = {struct_name}(bitfield & {mask} != 0);')
|
|
||||||
code.append(' },')
|
|
||||||
code.append(' }')
|
|
||||||
code.append(' }')
|
code.append(' }')
|
||||||
code.append(' Ok(())')
|
|
||||||
code.append(' }')
|
code.append(' }')
|
||||||
code.append('}')
|
code.append('}')
|
||||||
code.append('')
|
code.append('')
|
||||||
|
@ -349,29 +354,29 @@ impl From<EntityDataValue> for UpdateMetadataError {
|
||||||
|
|
||||||
# and now make the main update_metadata
|
# and now make the main update_metadata
|
||||||
# fn update_metadata(
|
# fn update_metadata(
|
||||||
# world: hecs::World,
|
# ecs: bevy_ecs::world::World,
|
||||||
# entity: hecs::Entity,
|
# entity: bevy_ecs::world::EntityMut,
|
||||||
# data: EntityMetadataItems,
|
# data: EntityMetadataItems,
|
||||||
# ) -> Result<(), UpdateMetadataError> {
|
# ) -> Result<(), UpdateMetadataError> {
|
||||||
# if let Ok(e) = world.query_one_mut::<AllayQuery>(entity) {
|
# if let Ok(e) = world.query_one_mut::<AllayBundle>(entity) {
|
||||||
# e.update_metadata(world, entity, data)?;
|
# e.update_metadata(ecs, entity, data)?;
|
||||||
# return Ok(());
|
# return Ok(());
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# Ok(())
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
code.append(
|
code.append(
|
||||||
f'fn update_metadata(world: hecs::World, entity: hecs::Entity, data: EntityMetadataItems) -> Result<(), UpdateMetadataError> {{')
|
f'fn update_metadata(ecs: bevy_ecs::world::World, entity: bevy_ecs::world::EntityMut, data: EntityMetadataItems) -> Result<(), UpdateMetadataError> {{')
|
||||||
for entity_id in burger_entity_data:
|
for entity_id in burger_entity_data:
|
||||||
if entity_id.startswith('~'):
|
if entity_id.startswith('~'):
|
||||||
# not actually an entiry
|
# not actually an entiry
|
||||||
continue
|
continue
|
||||||
struct_name: str = upper_first_letter(to_camel_case(entity_id))
|
struct_name: str = upper_first_letter(to_camel_case(entity_id))
|
||||||
query_struct_name = f'{struct_name}Query'
|
bundle_struct_name = f'{struct_name}Bundle'
|
||||||
code.append(
|
code.append(
|
||||||
f' if let Ok(e) = world.query_one_mut::<{query_struct_name}>(entity) {{')
|
f' if let Ok(e) = ecs.query_one_mut::<{bundle_struct_name}>(entity) {{')
|
||||||
code.append(
|
code.append(
|
||||||
f' e.update_metadata(world, entity, data)?;')
|
f' e.update_metadata(ecs, entity, data)?;')
|
||||||
code.append(f' return Ok(());')
|
code.append(f' return Ok(());')
|
||||||
code.append(' }')
|
code.append(' }')
|
||||||
code.append(' Ok(())')
|
code.append(' Ok(())')
|
||||||
|
|
|
@ -44,8 +44,8 @@ def burger_type_to_rust_type(burger_type, field_name: Optional[str] = None, inst
|
||||||
field_type_rs = 'String'
|
field_type_rs = 'String'
|
||||||
|
|
||||||
elif burger_type == 'chatcomponent':
|
elif burger_type == 'chatcomponent':
|
||||||
field_type_rs = 'Component'
|
field_type_rs = 'FormattedText'
|
||||||
uses.add('azalea_chat::Component')
|
uses.add('azalea_chat::FormattedText')
|
||||||
elif burger_type == 'identifier':
|
elif burger_type == 'identifier':
|
||||||
field_type_rs = 'ResourceLocation'
|
field_type_rs = 'ResourceLocation'
|
||||||
uses.add('azalea_core::ResourceLocation')
|
uses.add('azalea_core::ResourceLocation')
|
||||||
|
|
Loading…
Add table
Reference in a new issue