From f78dd795ca87d12c8299a876cebc7ee6c8079bb9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 24 Nov 2023 19:30:45 +0100 Subject: [PATCH] world/de: add deserialization of sign block entities --- src/world/chunk.rs | 7 ++-- src/world/de.rs | 79 ++++++++++++++++++++++++++++++++++++++++++ src/world/json_text.rs | 7 ++++ src/world/mod.rs | 1 + 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/world/json_text.rs diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 993a79e..cd3bf4f 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -60,9 +60,10 @@ impl<'a> Chunk<'a> { let data_version = data.data_version.unwrap_or_default(); match &data.chunk { - de::ChunkVariant::V1_18 { sections } => { - Self::new_v1_18(data_version, sections, block_types, biome_types) - } + de::ChunkVariant::V1_18 { + sections, + block_entities: _, + } => Self::new_v1_18(data_version, sections, block_types, biome_types), de::ChunkVariant::V0 { level } => { Self::new_v0(data_version, level, block_types, biome_types) } diff --git a/src/world/de.rs b/src/world/de.rs index cf1b6b5..7ab8ba7 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -2,6 +2,8 @@ use serde::Deserialize; +use super::json_text::JSONText; + /// Element of the `palette` list of 1.18+ [block states](BlockStatesV1_18) #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] @@ -104,6 +106,77 @@ pub enum BiomesV0 { ByteArray(fastnbt::ByteArray), } +/// Front/back text of a Minecraft 1.20+ sign block entry +#[derive(Debug, Deserialize)] +pub struct BlockEntitySignV1_20Text { + /// Lines of sign text + pub messages: Vec, + /// Default text color + pub color: Option, +} + +/// A sign (standing or hanging) block entity +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum BlockEntitySign { + /// Pre-1.20 sign block entity + /// + /// Pre-1.20 signs only have front text. + #[serde(rename_all = "PascalCase")] + V0 { + /// Line 1 of the sign text + text1: JSONText, + /// Line 2 of the sign text + text2: JSONText, + /// Line 3 of the sign text + text3: JSONText, + /// Line 4 of the sign text + text4: JSONText, + /// Default text color + color: Option, + }, + /// 1.20+ sign block entity + V1_20 { + /// The sign's front text + front_text: BlockEntitySignV1_20Text, + /// The sign's back text + back_text: BlockEntitySignV1_20Text, + }, +} + +/// Data for different kinds of block entities +#[derive(Debug, Deserialize)] +#[serde(tag = "id")] +pub enum BlockEntityData { + /// Regular sign + /// + /// This includes standing signs and signs attached to the side of blocks + #[serde(rename = "minecraft:sign", alias = "minecraft:standing_sign")] + Sign(BlockEntitySign), + /// Hanging sign + #[serde(rename = "minecraft:hanging_sign")] + HangingSign(BlockEntitySign), + /// Other block entity types not handled by MinedMap + #[serde(other)] + Other, +} + +/// A block entity +/// +/// Block entities were called tile entities pre-1.18 +#[derive(Debug, Deserialize)] +pub struct BlockEntity { + /// Entity global X coordinate + pub x: i32, + /// Entity global Y coordinate + pub y: i32, + /// Entity global Z coordinate + pub z: i32, + /// Kind-specific entity data + #[serde(flatten)] + pub data: BlockEntityData, +} + /// `Level` compound element found in pre-1.18 [chunks](Chunk) #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] @@ -113,6 +186,9 @@ pub struct LevelV0 { pub sections: Vec, /// Biome data pub biomes: Option, + /// List of block entities + #[serde(default)] + pub tile_entities: Vec, } /// Version-specific part of a [Chunk] compound @@ -123,6 +199,9 @@ pub enum ChunkVariant { V1_18 { /// List of chunk sections sections: Vec, + /// List of block entities + #[serde(default)] + block_entities: Vec, }, /// Pre-1.18 chunk data #[serde(rename_all = "PascalCase")] diff --git a/src/world/json_text.rs b/src/world/json_text.rs new file mode 100644 index 0000000..561725f --- /dev/null +++ b/src/world/json_text.rs @@ -0,0 +1,7 @@ +//! Newtype and helper methods for handling Minecraft Raw JSON Text + +use serde::Deserialize; + +/// Minecraft Raw JSON Text +#[derive(Debug, Deserialize)] +pub struct JSONText(String); diff --git a/src/world/mod.rs b/src/world/mod.rs index 57aa7ed..e3c52ba 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -2,5 +2,6 @@ pub mod chunk; pub mod de; +pub mod json_text; pub mod layer; pub mod section;