mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
fix ClientboundUpdateAdvancementsPacket
This commit is contained in:
parent
61db9f930a
commit
ec316e02cd
3 changed files with 128 additions and 91 deletions
|
@ -167,7 +167,6 @@ fn create_impl_mcbufwritable(ident: &Ident, data: &Data) -> proc_macro2::TokenSt
|
||||||
let mut variant_discrim: u32 = 0;
|
let mut variant_discrim: u32 = 0;
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
let variant_name = &variant.ident;
|
|
||||||
match &variant.discriminant.as_ref() {
|
match &variant.discriminant.as_ref() {
|
||||||
Some(d) => {
|
Some(d) => {
|
||||||
variant_discrim = match &d.1 {
|
variant_discrim = match &d.1 {
|
||||||
|
|
|
@ -126,18 +126,18 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
}
|
}
|
||||||
// if it's an object, do things with { text } and stuff
|
// if it's an object, do things with { text } and stuff
|
||||||
else if json.is_object() {
|
else if json.is_object() {
|
||||||
if json.get("text").is_some() {
|
if let Some(text) = json.get("text") {
|
||||||
let text = json.get("text").unwrap().as_str().unwrap_or("").to_string();
|
let text = text.as_str().unwrap_or("").to_string();
|
||||||
component = Component::Text(TextComponent::new(text));
|
component = Component::Text(TextComponent::new(text));
|
||||||
} else if json.get("translate").is_some() {
|
} else if let Some(translate) = json.get("translate") {
|
||||||
let translate = json
|
let translate = translate
|
||||||
.get("translate")
|
|
||||||
.unwrap()
|
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or_else(|| de::Error::custom("\"translate\" must be a string"))?
|
.ok_or_else(|| de::Error::custom("\"translate\" must be a string"))?
|
||||||
.into();
|
.into();
|
||||||
if json.get("with").is_some() {
|
if let Some(with) = json.get("with") {
|
||||||
let with = json.get("with").unwrap().as_array().unwrap();
|
let with = with
|
||||||
|
.as_array()
|
||||||
|
.ok_or_else(|| de::Error::custom("\"with\" must be an array"))?;
|
||||||
let mut with_array = Vec::with_capacity(with.len());
|
let mut with_array = Vec::with_capacity(with.len());
|
||||||
for item in with {
|
for item in with {
|
||||||
// if it's a string component with no styling and no siblings, just add a string to with_array
|
// if it's a string component with no styling and no siblings, just add a string to with_array
|
||||||
|
@ -162,12 +162,9 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
component =
|
component =
|
||||||
Component::Translatable(TranslatableComponent::new(translate, Vec::new()));
|
Component::Translatable(TranslatableComponent::new(translate, Vec::new()));
|
||||||
}
|
}
|
||||||
} else if json.get("score").is_some() {
|
} else if let Some(score) = json.get("score") {
|
||||||
// object = GsonHelper.getAsJsonObject(jsonObject, "score");
|
// object = GsonHelper.getAsJsonObject(jsonObject, "score");
|
||||||
let score_json = json.get("score").unwrap();
|
if score.get("name").is_none() || score.get("objective").is_none() {
|
||||||
// if (!object.has("name") || !object.has("objective")) throw new JsonParseException("A score component needs a least a name and an objective");
|
|
||||||
// ScoreComponent scoreComponent = new ScoreComponent(GsonHelper.getAsString((JsonObject)object, "name"), GsonHelper.getAsString((JsonObject)object, "objective"));
|
|
||||||
if score_json.get("name").is_none() || score_json.get("objective").is_none() {
|
|
||||||
return Err(de::Error::missing_field(
|
return Err(de::Error::missing_field(
|
||||||
"A score component needs at least a name and an objective",
|
"A score component needs at least a name and an objective",
|
||||||
));
|
));
|
||||||
|
@ -176,65 +173,35 @@ impl<'de> Deserialize<'de> for Component {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
"score text components aren't yet supported",
|
"score text components aren't yet supported",
|
||||||
));
|
));
|
||||||
// component = ScoreComponent
|
|
||||||
} else if json.get("selector").is_some() {
|
} else if json.get("selector").is_some() {
|
||||||
// } else if (jsonObject.has("selector")) {
|
|
||||||
// object = this.parseSeparator(type, jsonDeserializationContext, jsonObject);
|
|
||||||
// SelectorComponent selectorComponent = new SelectorComponent(GsonHelper.getAsString(jsonObject, "selector"), (Optional<Component>)object);
|
|
||||||
|
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
"selector text components aren't yet supported",
|
"selector text components aren't yet supported",
|
||||||
));
|
));
|
||||||
// } else if (jsonObject.has("keybind")) {
|
|
||||||
// KeybindComponent keybindComponent = new KeybindComponent(GsonHelper.getAsString(jsonObject, "keybind"));
|
|
||||||
} else if json.get("keybind").is_some() {
|
} else if json.get("keybind").is_some() {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
"keybind text components aren't yet supported",
|
"keybind text components aren't yet supported",
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
// } else {
|
let nbt = if let Some(nbt) = json.get("nbt") {
|
||||||
// if (!jsonObject.has("nbt")) throw new JsonParseException("Don't know how to turn " + jsonElement + " into a Component");
|
nbt
|
||||||
if json.get("nbt").is_none() {
|
} else {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
format!("Don't know how to turn {} into a Component", json).as_str(),
|
format!("Don't know how to turn {} into a Component", json).as_str(),
|
||||||
));
|
));
|
||||||
}
|
};
|
||||||
// object = GsonHelper.getAsString(jsonObject, "nbt");
|
|
||||||
let _nbt = json.get("nbt").unwrap().to_string();
|
|
||||||
// Optional<Component> optional = this.parseSeparator(type, jsonDeserializationContext, jsonObject);
|
|
||||||
let _separator = Component::parse_separator(&json).map_err(de::Error::custom)?;
|
let _separator = Component::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(),
|
||||||
None => false,
|
None => false,
|
||||||
};
|
};
|
||||||
// boolean bl = GsonHelper.getAsBoolean(jsonObject, "interpret", false);
|
if let Some(_block) = json.get("block") {}
|
||||||
// if (jsonObject.has("block")) {
|
|
||||||
if json.get("block").is_some() {}
|
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
"nbt text components aren't yet supported",
|
"nbt text components aren't yet supported",
|
||||||
));
|
));
|
||||||
// NbtComponent.BlockNbtComponent blockNbtComponent = new NbtComponent.BlockNbtComponent((String)object, bl, GsonHelper.getAsString(jsonObject, "block"), optional);
|
|
||||||
// } else if (jsonObject.has("entity")) {
|
|
||||||
// NbtComponent.EntityNbtComponent entityNbtComponent = new NbtComponent.EntityNbtComponent((String)object, bl, GsonHelper.getAsString(jsonObject, "entity"), optional);
|
|
||||||
// } else {
|
|
||||||
// if (!jsonObject.has("storage")) throw new JsonParseException("Don't know how to turn " + jsonElement + " into a Component");
|
|
||||||
// NbtComponent.StorageNbtComponent storageNbtComponent = new NbtComponent.StorageNbtComponent((String)object, bl, new ResourceLocation(GsonHelper.getAsString(jsonObject, "storage")), optional);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// if (jsonObject.has("extra")) {
|
if let Some(extra) = json.get("extra") {
|
||||||
// object = GsonHelper.getAsJsonArray(jsonObject, "extra");
|
let extra = match extra.as_array() {
|
||||||
// if (object.size() <= 0) throw new JsonParseException("Unexpected empty array of components");
|
|
||||||
// for (int i = 0; i < object.size(); ++i) {
|
|
||||||
// var5_17.append(this.deserialize(object.get(i), type, jsonDeserializationContext));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// var5_17.setStyle((Style)jsonDeserializationContext.deserialize(jsonElement, Style.class));
|
|
||||||
// return var5_17;
|
|
||||||
// }
|
|
||||||
if json.get("extra").is_some() {
|
|
||||||
let extra = match json.get("extra").unwrap().as_array() {
|
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => return Err(de::Error::custom("Extra isn't an array")),
|
None => return Err(de::Error::custom("Extra isn't an array")),
|
||||||
};
|
};
|
||||||
|
@ -281,18 +248,10 @@ impl McBufReadable for Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McBufWritable for Component {
|
impl McBufWritable for Component {
|
||||||
// async fn read_from(buf: &mut impl Read) -> Result<Self, String>
|
|
||||||
// where
|
|
||||||
// R: AsyncRead + std::marker::Unpin + std::marker::Send,
|
|
||||||
// {
|
|
||||||
// let string = String::read_from(buf).await?;
|
|
||||||
// let json: serde_json::Value = serde_json::from_str(string.as_str())
|
|
||||||
// .map_err(|e| "Component isn't valid JSON".to_string())?;
|
|
||||||
// let component = Component::deserialize(json).map_err(|e| e.to_string())?;
|
|
||||||
// Ok(component)
|
|
||||||
// }
|
|
||||||
fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> {
|
fn write_into(&self, _buf: &mut impl Write) -> Result<(), std::io::Error> {
|
||||||
// component doesn't have serialize implemented yet
|
// let json = serde_json::to_string(self).unwrap();
|
||||||
|
// json.write_into(_buf);
|
||||||
|
// Ok(())
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
|
use azalea_buf::McBuf;
|
||||||
use azalea_chat::component::Component;
|
use azalea_chat::component::Component;
|
||||||
use azalea_core::{ResourceLocation, Slot};
|
use azalea_core::{ResourceLocation, Slot};
|
||||||
use azalea_protocol_macros::ClientboundGamePacket;
|
use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
use std::{
|
use std::collections::HashMap;
|
||||||
collections::HashMap,
|
|
||||||
io::{Read, Write},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||||
pub struct ClientboundUpdateAdvancementsPacket {
|
pub struct ClientboundUpdateAdvancementsPacket {
|
||||||
|
@ -25,40 +22,28 @@ pub struct Advancement {
|
||||||
// requirements_strategy: RequirementsStrategy.AND
|
// requirements_strategy: RequirementsStrategy.AND
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, McBuf)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DisplayInfo {
|
pub struct DisplayInfo {
|
||||||
pub title: Component,
|
pub title: Component,
|
||||||
pub description: Component,
|
pub description: Component,
|
||||||
pub icon: Slot,
|
pub icon: Slot,
|
||||||
pub frame: FrameType,
|
pub frame: FrameType,
|
||||||
pub flags: DisplayFlags,
|
pub show_toast: bool,
|
||||||
|
pub hidden: bool,
|
||||||
pub background: Option<ResourceLocation>,
|
pub background: Option<ResourceLocation>,
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
pub y: f32,
|
pub y: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
impl azalea_buf::McBufWritable for DisplayInfo {
|
||||||
pub struct DisplayFlags {
|
fn write_into(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
|
||||||
pub background: bool,
|
self.title.write_into(buf)?;
|
||||||
pub show_toast: bool,
|
self.description.write_into(buf)?;
|
||||||
pub hidden: bool,
|
self.icon.write_into(buf)?;
|
||||||
}
|
self.frame.write_into(buf)?;
|
||||||
|
|
||||||
impl McBufReadable for DisplayFlags {
|
let mut data: u32 = 0;
|
||||||
fn read_from(buf: &mut impl Read) -> Result<Self, BufReadError> {
|
if self.background.is_some() {
|
||||||
let data = u32::read_from(buf)?;
|
|
||||||
Ok(DisplayFlags {
|
|
||||||
background: (data & 0b1) != 0,
|
|
||||||
show_toast: (data & 0b10) != 0,
|
|
||||||
hidden: (data & 0b100) != 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl McBufWritable for DisplayFlags {
|
|
||||||
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
|
|
||||||
let mut data = 0;
|
|
||||||
if self.background {
|
|
||||||
data |= 0b1;
|
data |= 0b1;
|
||||||
}
|
}
|
||||||
if self.show_toast {
|
if self.show_toast {
|
||||||
|
@ -67,7 +52,46 @@ impl McBufWritable for DisplayFlags {
|
||||||
if self.hidden {
|
if self.hidden {
|
||||||
data |= 0b100;
|
data |= 0b100;
|
||||||
}
|
}
|
||||||
u32::write_into(&data, buf)
|
data.write_into(buf)?;
|
||||||
|
|
||||||
|
if let Some(background) = &self.background {
|
||||||
|
background.write_into(buf)?;
|
||||||
|
}
|
||||||
|
self.x.write_into(buf)?;
|
||||||
|
self.y.write_into(buf)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl azalea_buf::McBufReadable for DisplayInfo {
|
||||||
|
fn read_from(buf: &mut impl std::io::Read) -> Result<Self, azalea_buf::BufReadError> {
|
||||||
|
let title = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
let description = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
let icon = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
let frame = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
|
||||||
|
let data = u32::read_from(buf)?;
|
||||||
|
let has_background = (data & 0b1) != 0;
|
||||||
|
let show_toast = (data & 0b10) != 0;
|
||||||
|
let hidden = (data & 0b100) != 0;
|
||||||
|
|
||||||
|
let background = if has_background {
|
||||||
|
Some(ResourceLocation::read_from(buf)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let x = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
let y = azalea_buf::McBufReadable::read_from(buf)?;
|
||||||
|
Ok(DisplayInfo {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
icon,
|
||||||
|
frame,
|
||||||
|
background,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
hidden,
|
||||||
|
show_toast,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,3 +112,58 @@ pub type AdvancementProgress = HashMap<ResourceLocation, CriterionProgress>;
|
||||||
pub struct CriterionProgress {
|
pub struct CriterionProgress {
|
||||||
date: Option<u64>,
|
date: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[cfg(test)]
|
||||||
|
// mod tests {
|
||||||
|
// use super::*;
|
||||||
|
// use azalea_buf::{McBufReadable, McBufWritable};
|
||||||
|
// use azalea_core::ResourceLocation;
|
||||||
|
// use azalea_protocol_macros::ClientboundGamePacket;
|
||||||
|
// use std::io::Cursor;
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn test() {
|
||||||
|
// let mut buf = Cursor::new(Vec::new());
|
||||||
|
// let packet = ClientboundUpdateAdvancementsPacket {
|
||||||
|
// reset: true,
|
||||||
|
// added: [(
|
||||||
|
// ResourceLocation::new("minecraft:test").unwrap(),
|
||||||
|
// Advancement {
|
||||||
|
// parent_id: None,
|
||||||
|
// display: Some(DisplayInfo {
|
||||||
|
// title: Component::from("title".to_string()),
|
||||||
|
// description: Component::from("description".to_string()),
|
||||||
|
// icon: Slot::Empty,
|
||||||
|
// frame: FrameType::Task,
|
||||||
|
// show_toast: true,
|
||||||
|
// hidden: false,
|
||||||
|
// background: None,
|
||||||
|
// x: 0.0,
|
||||||
|
// y: 0.0,
|
||||||
|
// }),
|
||||||
|
// criteria: HashMap::new(),
|
||||||
|
// requirements: Vec::new(),
|
||||||
|
// },
|
||||||
|
// )]
|
||||||
|
// .into_iter()
|
||||||
|
// .collect(),
|
||||||
|
// removed: vec![ResourceLocation::new("minecraft:test2").unwrap()],
|
||||||
|
// progress: [(
|
||||||
|
// ResourceLocation::new("minecraft:test3").unwrap(),
|
||||||
|
// [(
|
||||||
|
// ResourceLocation::new("minecraft:test4").unwrap(),
|
||||||
|
// CriterionProgress {
|
||||||
|
// date: Some(123456789),
|
||||||
|
// },
|
||||||
|
// )]
|
||||||
|
// .into_iter()
|
||||||
|
// .collect(),
|
||||||
|
// )]
|
||||||
|
// .into_iter()
|
||||||
|
// .collect(),
|
||||||
|
// };
|
||||||
|
// packet.write_into(&mut buf).unwrap();
|
||||||
|
// let packet = ClientboundUpdateAdvancementsPacket::read_from(&mut buf).unwrap();
|
||||||
|
// assert_eq!(packet.reset, true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
Loading…
Add table
Reference in a new issue