mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
world: process sign data, prepare for serialization
This commit is contained in:
parent
638d5046c9
commit
f0e0db63d3
5 changed files with 130 additions and 11 deletions
89
src/world/block_entity.rs
Normal file
89
src/world/block_entity.rs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
//! Processing of block entity data
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
de,
|
||||||
|
sign::{BlockEntitySignExt, SignText},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Kind of sign block
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum SignKind {
|
||||||
|
/// Standing or attached sign
|
||||||
|
Sign,
|
||||||
|
/// Hanging sign
|
||||||
|
HangingSign,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Processed sign data
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Sign {
|
||||||
|
/// The kind of the sign
|
||||||
|
pub kind: SignKind,
|
||||||
|
/// The sign's front text
|
||||||
|
#[serde(skip_serializing_if = "SignText::is_empty", default)]
|
||||||
|
pub front_text: SignText,
|
||||||
|
/// The sign's back text
|
||||||
|
#[serde(skip_serializing_if = "SignText::is_empty", default)]
|
||||||
|
pub back_text: SignText,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sign {
|
||||||
|
/// Processes a [de::BlockEntitySign] into a [Sign]
|
||||||
|
fn new(sign: &de::BlockEntitySign, kind: SignKind) -> Sign {
|
||||||
|
let (front_text, back_text) = sign.text();
|
||||||
|
let front_text = front_text.decode();
|
||||||
|
let back_text = back_text.decode();
|
||||||
|
Sign {
|
||||||
|
kind,
|
||||||
|
front_text,
|
||||||
|
back_text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data for different kinds of [BlockEntity]
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
|
pub enum BlockEntityData {
|
||||||
|
/// A sign block
|
||||||
|
Sign(Sign),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A processed block entity
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BlockEntity {
|
||||||
|
/// Global X coordinate
|
||||||
|
pub x: i32,
|
||||||
|
/// Global Y coordinate
|
||||||
|
pub y: i32,
|
||||||
|
/// Global Z coordinate
|
||||||
|
pub z: i32,
|
||||||
|
/// Entity data
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub data: BlockEntityData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockEntity {
|
||||||
|
/// Processes a [de::BlockEntity] into a [BlockEntity]
|
||||||
|
pub fn new(entity: &de::BlockEntity) -> Option<Self> {
|
||||||
|
let data = match &entity.data {
|
||||||
|
de::BlockEntityData::Sign(sign) => {
|
||||||
|
BlockEntityData::Sign(Sign::new(sign, SignKind::Sign))
|
||||||
|
}
|
||||||
|
de::BlockEntityData::HangingSign(sign) => {
|
||||||
|
BlockEntityData::Sign(Sign::new(sign, SignKind::HangingSign))
|
||||||
|
}
|
||||||
|
de::BlockEntityData::Other => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(BlockEntity {
|
||||||
|
x: entity.x,
|
||||||
|
y: entity.y,
|
||||||
|
z: entity.z,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ use std::{
|
||||||
|
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
|
|
||||||
use super::{de, section::*};
|
use super::{block_entity::BlockEntity, de, section::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
resource::{BiomeTypes, BlockTypes},
|
resource::{BiomeTypes, BlockTypes},
|
||||||
types::*,
|
types::*,
|
||||||
|
@ -55,6 +55,8 @@ pub enum ChunkInner<'a> {
|
||||||
pub struct Chunk<'a> {
|
pub struct Chunk<'a> {
|
||||||
/// Version-specific data
|
/// Version-specific data
|
||||||
inner: ChunkInner<'a>,
|
inner: ChunkInner<'a>,
|
||||||
|
/// Unprocessed block entities
|
||||||
|
block_entities: &'a Vec<de::BlockEntity>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Chunk<'a> {
|
impl<'a> Chunk<'a> {
|
||||||
|
@ -66,17 +68,27 @@ impl<'a> Chunk<'a> {
|
||||||
) -> Result<(Self, bool)> {
|
) -> Result<(Self, bool)> {
|
||||||
let data_version = data.data_version.unwrap_or_default();
|
let data_version = data.data_version.unwrap_or_default();
|
||||||
|
|
||||||
let (inner, has_unknown) = match &data.chunk {
|
let ((inner, has_unknown), block_entities) = match &data.chunk {
|
||||||
de::ChunkVariant::V1_18 {
|
de::ChunkVariant::V1_18 {
|
||||||
sections,
|
sections,
|
||||||
block_entities: _,
|
block_entities,
|
||||||
} => Self::new_v1_18(data_version, sections, block_types, biome_types)?,
|
} => (
|
||||||
de::ChunkVariant::V0 { level } => {
|
Self::new_v1_18(data_version, sections, block_types, biome_types)?,
|
||||||
Self::new_v0(data_version, level, block_types, biome_types)?
|
block_entities,
|
||||||
}
|
),
|
||||||
|
de::ChunkVariant::V0 { level } => (
|
||||||
|
Self::new_v0(data_version, level, block_types, biome_types)?,
|
||||||
|
&level.tile_entities,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((Chunk { inner }, has_unknown))
|
Ok((
|
||||||
|
Chunk {
|
||||||
|
inner,
|
||||||
|
block_entities,
|
||||||
|
},
|
||||||
|
has_unknown,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Chunk::new] implementation for Minecraft v1.18+ chunks
|
/// [Chunk::new] implementation for Minecraft v1.18+ chunks
|
||||||
|
@ -230,6 +242,14 @@ impl<'a> Chunk<'a> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Processes all of the chunk's block entities
|
||||||
|
pub fn block_entities(&self) -> Vec<BlockEntity> {
|
||||||
|
self.block_entities
|
||||||
|
.iter()
|
||||||
|
.filter_map(BlockEntity::new)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference to block, biome and block light data of a section
|
/// Reference to block, biome and block light data of a section
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::{collections::VecDeque, sync::Arc};
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A span of formatted text
|
/// A span of formatted text
|
||||||
///
|
///
|
||||||
|
@ -11,22 +11,28 @@ use serde::Deserialize;
|
||||||
/// is handled by [DeserializedText].
|
/// is handled by [DeserializedText].
|
||||||
///
|
///
|
||||||
/// Formatting that is not set in a node is inherited from the parent.
|
/// Formatting that is not set in a node is inherited from the parent.
|
||||||
#[derive(Debug, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
pub struct FormattedText {
|
pub struct FormattedText {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
/// Text content
|
/// Text content
|
||||||
pub text: String,
|
pub text: String,
|
||||||
/// Text color
|
/// Text color
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub color: Option<Arc<String>>,
|
pub color: Option<Arc<String>>,
|
||||||
/// Bold formatting
|
/// Bold formatting
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub bold: Option<bool>,
|
pub bold: Option<bool>,
|
||||||
/// Italic formatting
|
/// Italic formatting
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub italic: Option<bool>,
|
pub italic: Option<bool>,
|
||||||
/// Underlines formatting
|
/// Underlines formatting
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub underlined: Option<bool>,
|
pub underlined: Option<bool>,
|
||||||
/// Strikethrough formatting
|
/// Strikethrough formatting
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub strikethrough: Option<bool>,
|
pub strikethrough: Option<bool>,
|
||||||
/// Obfuscated formatting
|
/// Obfuscated formatting
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub obfuscated: Option<bool>,
|
pub obfuscated: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +77,7 @@ impl From<String> for FormattedTextTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of [FormattedText]
|
/// List of [FormattedText]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct FormattedTextList(pub Vec<FormattedText>);
|
pub struct FormattedTextList(pub Vec<FormattedText>);
|
||||||
|
|
||||||
impl FormattedTextList {
|
impl FormattedTextList {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Data structures describing Minecraft save data
|
//! Data structures describing Minecraft save data
|
||||||
|
|
||||||
|
pub mod block_entity;
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod json_text;
|
pub mod json_text;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
de,
|
de,
|
||||||
json_text::{FormattedText, FormattedTextList, JSONText},
|
json_text::{FormattedText, FormattedTextList, JSONText},
|
||||||
|
@ -77,6 +79,7 @@ impl BlockEntitySignExt for de::BlockEntitySign {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
/// Deserialized and linearized sign text
|
/// Deserialized and linearized sign text
|
||||||
pub struct SignText(pub Vec<FormattedTextList>);
|
pub struct SignText(pub Vec<FormattedTextList>);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue