mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
fix CustomModelData and WrittenBookContent datacomponents
This commit is contained in:
parent
c285fadd34
commit
63b1036a96
7 changed files with 126 additions and 6 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -432,6 +432,7 @@ dependencies = [
|
|||
"azalea-registry",
|
||||
"indexmap",
|
||||
"simdnbt",
|
||||
"tracing",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ pub enum BufReadError {
|
|||
CouldNotReadBytes,
|
||||
#[error("The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})")]
|
||||
StringLengthTooLong { length: u32, max_length: u32 },
|
||||
#[error("The received Vec length is longer than maximum allowed ({length} > {max_length})")]
|
||||
VecLengthTooLong { length: u32, max_length: u32 },
|
||||
#[error("{source}")]
|
||||
Io {
|
||||
#[from]
|
||||
|
@ -183,7 +185,7 @@ impl AzaleaRead for UnsizedByteArray {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: AzaleaRead + Send> AzaleaRead for Vec<T> {
|
||||
impl<T: AzaleaRead> AzaleaRead for Vec<T> {
|
||||
default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||
let length = u32::azalea_read_var(buf)? as usize;
|
||||
// we limit the capacity to not get exploited into allocating a bunch
|
||||
|
@ -194,6 +196,23 @@ impl<T: AzaleaRead + Send> AzaleaRead for Vec<T> {
|
|||
Ok(contents)
|
||||
}
|
||||
}
|
||||
impl<T: AzaleaRead> AzaleaReadLimited for Vec<T> {
|
||||
fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
|
||||
let length = u32::azalea_read_var(buf)? as usize;
|
||||
if length > limit {
|
||||
return Err(BufReadError::VecLengthTooLong {
|
||||
length: length as u32,
|
||||
max_length: limit as u32,
|
||||
});
|
||||
}
|
||||
|
||||
let mut contents = Vec::with_capacity(usize::min(length, 65536));
|
||||
for _ in 0..length {
|
||||
contents.push(T::azalea_read(buf)?);
|
||||
}
|
||||
Ok(contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for HashMap<K, V> {
|
||||
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
|
||||
|
@ -343,6 +362,16 @@ impl<T: AzaleaReadVar> AzaleaReadVar for Option<T> {
|
|||
})
|
||||
}
|
||||
}
|
||||
impl<T: AzaleaReadLimited> AzaleaReadLimited for Option<T> {
|
||||
fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
|
||||
let present = bool::azalea_read(buf)?;
|
||||
Ok(if present {
|
||||
Some(T::azalea_read_limited(buf, limit)?)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// [String; 4]
|
||||
impl<T: AzaleaRead, const N: usize> AzaleaRead for [T; N] {
|
||||
|
|
55
azalea-core/src/filterable.rs
Normal file
55
azalea-core/src/filterable.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use std::io::Cursor;
|
||||
|
||||
use azalea_buf::{AzaleaRead, AzaleaReadLimited, AzaleaReadVar, AzaleaWrite};
|
||||
|
||||
/// Used for written books.
|
||||
pub struct Filterable<T> {
|
||||
pub raw: T,
|
||||
pub filtered: Option<T>,
|
||||
}
|
||||
|
||||
impl<T: AzaleaWrite> azalea_buf::AzaleaWrite for Filterable<T> {
|
||||
fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
|
||||
self.raw.azalea_write(buf)?;
|
||||
self.filtered.azalea_write(buf)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl<T: AzaleaRead> azalea_buf::AzaleaRead for Filterable<T> {
|
||||
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
|
||||
let raw = AzaleaRead::azalea_read(buf)?;
|
||||
let filtered = AzaleaRead::azalea_read(buf)?;
|
||||
Ok(Self { raw, filtered })
|
||||
}
|
||||
}
|
||||
impl<T: AzaleaReadLimited> azalea_buf::AzaleaReadLimited for Filterable<T> {
|
||||
fn azalea_read_limited(
|
||||
buf: &mut Cursor<&[u8]>,
|
||||
limit: usize,
|
||||
) -> Result<Self, azalea_buf::BufReadError> {
|
||||
let raw = AzaleaReadLimited::azalea_read_limited(buf, limit)?;
|
||||
let filtered = AzaleaReadLimited::azalea_read_limited(buf, limit)?;
|
||||
Ok(Self { raw, filtered })
|
||||
}
|
||||
}
|
||||
impl<T: AzaleaReadVar> azalea_buf::AzaleaReadVar for Filterable<T> {
|
||||
fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
|
||||
let raw = AzaleaReadVar::azalea_read_var(buf)?;
|
||||
let filtered = AzaleaReadVar::azalea_read_var(buf)?;
|
||||
Ok(Self { raw, filtered })
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for Filterable<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
raw: self.raw.clone(),
|
||||
filtered: self.filtered.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: PartialEq> PartialEq for Filterable<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.raw == other.raw && self.filtered == other.filtered
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ pub mod data_registry;
|
|||
pub mod delta;
|
||||
pub mod difficulty;
|
||||
pub mod direction;
|
||||
pub mod filterable;
|
||||
pub mod game_type;
|
||||
pub mod math;
|
||||
pub mod objectives;
|
||||
|
|
|
@ -17,4 +17,5 @@ azalea-registry = { path = "../azalea-registry", version = "0.11.0" }
|
|||
indexmap.workspace = true
|
||||
|
||||
simdnbt.workspace = true
|
||||
tracing.workspace = true
|
||||
uuid.workspace = true
|
||||
|
|
|
@ -3,12 +3,15 @@ use std::{any::Any, collections::HashMap, io::Cursor};
|
|||
|
||||
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
|
||||
use azalea_chat::FormattedText;
|
||||
use azalea_core::{position::GlobalPos, resource_location::ResourceLocation};
|
||||
use azalea_core::{
|
||||
filterable::Filterable, position::GlobalPos, resource_location::ResourceLocation,
|
||||
};
|
||||
use azalea_registry::{
|
||||
Attribute, Block, ConsumeEffectKind, DataComponentKind, Enchantment, EntityKind, HolderSet,
|
||||
Item, MobEffect, Potion, SoundEvent, TrimMaterial, TrimPattern,
|
||||
};
|
||||
use simdnbt::owned::{Nbt, NbtCompound};
|
||||
use tracing::trace;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::ItemStack;
|
||||
|
@ -54,6 +57,8 @@ pub fn from_kind(
|
|||
// if this is causing a compile-time error, look at DataComponents.java in the
|
||||
// decompiled vanilla code to see how to implement new components
|
||||
|
||||
trace!("Reading data component {kind}");
|
||||
|
||||
// note that this match statement is updated by genitemcomponents.py
|
||||
Ok(match kind {
|
||||
DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?),
|
||||
|
@ -328,8 +333,10 @@ impl DataComponent for AttributeModifiers {
|
|||
|
||||
#[derive(Clone, PartialEq, AzBuf)]
|
||||
pub struct CustomModelData {
|
||||
#[var]
|
||||
pub value: i32,
|
||||
pub floats: Vec<f32>,
|
||||
pub flags: Vec<bool>,
|
||||
pub strings: Vec<String>,
|
||||
pub colors: Vec<i32>,
|
||||
}
|
||||
impl DataComponent for CustomModelData {
|
||||
const KIND: DataComponentKind = DataComponentKind::CustomModelData;
|
||||
|
@ -535,13 +542,15 @@ impl DataComponent for WritableBookContent {
|
|||
|
||||
#[derive(Clone, PartialEq, AzBuf)]
|
||||
pub struct WrittenBookContent {
|
||||
pub title: String,
|
||||
#[limit(32)]
|
||||
pub title: Filterable<String>,
|
||||
pub author: String,
|
||||
#[var]
|
||||
pub generation: i32,
|
||||
pub pages: Vec<FormattedText>,
|
||||
pub pages: Vec<Filterable<FormattedText>>,
|
||||
pub resolved: bool,
|
||||
}
|
||||
|
||||
impl DataComponent for WrittenBookContent {
|
||||
const KIND: DataComponentKind = DataComponentKind::WrittenBookContent;
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue