treewide: rename "old" data structures to "v0"

"v0" doesn't refer to a specific version of Minecraft; it is just the
oldest data format supported by MinedMap.
This commit is contained in:
Matthias Schiffer 2023-02-12 22:54:43 +01:00
parent 493608ebc8
commit 9146c06bec
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 62 additions and 64 deletions

View file

@ -7,7 +7,7 @@ use anyhow::{bail, Context, Result};
use super::{ use super::{
de, de,
section::{OldSection, PaletteSection, PaletteSectionBiomes, Section}, section::{BiomesV18, Section, SectionV0, SectionV1_13},
}; };
use crate::types::*; use crate::types::*;
@ -17,7 +17,7 @@ use crate::types::*;
pub enum Chunk<'a> { pub enum Chunk<'a> {
/// Minecraft v1.18+ chunk with biome data moved into sections /// Minecraft v1.18+ chunk with biome data moved into sections
V1_18 { V1_18 {
section_map: BTreeMap<SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>, section_map: BTreeMap<SectionY, (SectionV1_13<'a>, BiomesV18<'a>)>,
}, },
/// Minecraft v1.13+ chunk /// Minecraft v1.13+ chunk
/// ///
@ -26,15 +26,15 @@ pub enum Chunk<'a> {
/// section), and a palette mapping these indices to namespaced /// section), and a palette mapping these indices to namespaced
/// block IDs /// block IDs
V1_13 { V1_13 {
section_map: BTreeMap<SectionY, PaletteSection<'a>>, section_map: BTreeMap<SectionY, SectionV1_13<'a>>,
biomes: &'a de::BiomesOld, biomes: &'a de::BiomesV0,
}, },
/// Original pre-1.13 chunk /// Original pre-1.13 chunk
/// ///
/// The original chunk format with fixed 8-bit numeric block IDs /// The original chunk format with fixed 8-bit numeric block IDs
Old { V0 {
section_map: BTreeMap<SectionY, OldSection<'a>>, section_map: BTreeMap<SectionY, SectionV0<'a>>,
biomes: &'a de::BiomesOld, biomes: &'a de::BiomesV0,
}, },
/// Unpopulated chunk without any block data /// Unpopulated chunk without any block data
Empty, Empty,
@ -45,15 +45,15 @@ pub enum Chunk<'a> {
enum SectionIterInner<'a> { enum SectionIterInner<'a> {
/// Iterator over sections of [Chunk::V1_18] /// Iterator over sections of [Chunk::V1_18]
V1_18 { V1_18 {
iter: btree_map::Iter<'a, SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>, iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV18<'a>)>,
}, },
/// Iterator over sections of [Chunk::V1_13] /// Iterator over sections of [Chunk::V1_13]
V1_13 { V1_13 {
iter: btree_map::Iter<'a, SectionY, PaletteSection<'a>>, iter: btree_map::Iter<'a, SectionY, SectionV1_13<'a>>,
}, },
/// Iterator over sections of [Chunk::Old] /// Iterator over sections of [Chunk::V0]
Old { V0 {
iter: btree_map::Iter<'a, SectionY, OldSection<'a>>, iter: btree_map::Iter<'a, SectionY, SectionV0<'a>>,
}, },
/// Empty iterator over an unpopulated chunk ([Chunk::Empty]) /// Empty iterator over an unpopulated chunk ([Chunk::Empty])
Empty, Empty,
@ -72,7 +72,7 @@ impl<'a> Chunk<'a> {
match &data.chunk { match &data.chunk {
de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections), de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections),
de::ChunkVariants::Old { level } => Self::new_old(data_version, level), de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level),
} }
} }
@ -84,17 +84,16 @@ impl<'a> Chunk<'a> {
section_map.insert( section_map.insert(
SectionY(section.y), SectionY(section.y),
( (
PaletteSection::new( SectionV1_13::new(
data_version, data_version,
section.block_states.data.as_ref(), section.block_states.data.as_ref(),
&section.block_states.palette, &section.block_states.palette,
) )
.with_context(|| format!("Failed to load section at Y={}", section.y))?, .with_context(|| format!("Failed to load section at Y={}", section.y))?,
PaletteSectionBiomes::new( BiomesV18::new(section.biomes.data.as_ref(), &section.biomes.palette)
section.biomes.data.as_ref(), .with_context(|| {
&section.biomes.palette, format!("Failed to load section biomes at Y={}", section.y)
) })?,
.with_context(|| format!("Failed to load section biomes at Y={}", section.y))?,
), ),
); );
} }
@ -103,33 +102,32 @@ impl<'a> Chunk<'a> {
} }
/// [Chunk::new] implementation for all pre-1.18 chunk variants /// [Chunk::new] implementation for all pre-1.18 chunk variants
fn new_old(data_version: u32, level: &'a de::LevelOld) -> Result<Self> { fn new_v0(data_version: u32, level: &'a de::LevelV0) -> Result<Self> {
let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v1_13 = BTreeMap::new();
let mut section_map_old = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new();
for section in &level.sections { for section in &level.sections {
match &section.section { match &section.section {
de::SectionOldVariants::V1_13 { de::SectionV0Variants::V1_13 {
block_states, block_states,
palette, palette,
} => { } => {
section_map_v1_13.insert( section_map_v1_13.insert(
SectionY(section.y.into()), SectionY(section.y.into()),
PaletteSection::new(data_version, Some(block_states), palette) SectionV1_13::new(data_version, Some(block_states), palette).with_context(
.with_context(|| { || format!("Failed to load section at Y={}", section.y),
format!("Failed to load section at Y={}", section.y) )?,
})?,
); );
} }
de::SectionOldVariants::Old { blocks, data } => { de::SectionV0Variants::V0 { blocks, data } => {
section_map_old.insert( section_map_v0.insert(
SectionY(section.y.into()), SectionY(section.y.into()),
OldSection::new(blocks, data).with_context(|| { SectionV0::new(blocks, data).with_context(|| {
format!("Failed to load section at Y={}", section.y) format!("Failed to load section at Y={}", section.y)
})?, })?,
); );
} }
de::SectionOldVariants::Empty {} => {} de::SectionV0Variants::Empty {} => {}
} }
} }
@ -137,14 +135,14 @@ impl<'a> Chunk<'a> {
let biomes = level.biomes.as_ref().context("Invalid biome data"); let biomes = level.biomes.as_ref().context("Invalid biome data");
Ok( Ok(
match (section_map_v1_13.is_empty(), section_map_old.is_empty()) { match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) {
(true, true) => Chunk::Empty, (true, true) => Chunk::Empty,
(false, true) => Chunk::V1_13 { (false, true) => Chunk::V1_13 {
section_map: section_map_v1_13, section_map: section_map_v1_13,
biomes: biomes?, biomes: biomes?,
}, },
(true, false) => Chunk::Old { (true, false) => Chunk::V0 {
section_map: section_map_old, section_map: section_map_v0,
biomes: biomes?, biomes: biomes?,
}, },
(false, false) => { (false, false) => {
@ -165,7 +163,7 @@ impl<'a> Chunk<'a> {
Chunk::V1_13 { section_map, .. } => V1_13 { Chunk::V1_13 { section_map, .. } => V1_13 {
iter: section_map.iter(), iter: section_map.iter(),
}, },
Chunk::Old { section_map, .. } => Old { Chunk::V0 { section_map, .. } => V0 {
iter: section_map.iter(), iter: section_map.iter(),
}, },
Chunk::Empty => Empty, Chunk::Empty => Empty,
@ -202,7 +200,7 @@ impl<'a> SectionIter<'a> {
SectionIterInner::V1_13 { iter } => { SectionIterInner::V1_13 { iter } => {
f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) }))
} }
SectionIterInner::Old { iter } => { SectionIterInner::V0 { iter } => {
f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) }))
} }
SectionIterInner::Empty => f(&mut iter::empty()), SectionIterInner::Empty => f(&mut iter::empty()),
@ -221,7 +219,7 @@ impl<'a> Iterator for SectionIter<'a> {
match &self.inner { match &self.inner {
SectionIterInner::V1_18 { iter } => iter.size_hint(), SectionIterInner::V1_18 { iter } => iter.size_hint(),
SectionIterInner::V1_13 { iter } => iter.size_hint(), SectionIterInner::V1_13 { iter } => iter.size_hint(),
SectionIterInner::Old { iter } => iter.size_hint(), SectionIterInner::V0 { iter } => iter.size_hint(),
SectionIterInner::Empty => (0, Some(0)), SectionIterInner::Empty => (0, Some(0)),
} }
} }
@ -242,7 +240,7 @@ impl<'a> ExactSizeIterator for SectionIter<'a> {
match &self.inner { match &self.inner {
SectionIterInner::V1_18 { iter } => iter.len(), SectionIterInner::V1_18 { iter } => iter.len(),
SectionIterInner::V1_13 { iter } => iter.len(), SectionIterInner::V1_13 { iter } => iter.len(),
SectionIterInner::Old { iter } => iter.len(), SectionIterInner::V0 { iter } => iter.len(),
SectionIterInner::Empty => 0, SectionIterInner::Empty => 0,
} }
} }

View file

@ -34,37 +34,37 @@ pub struct SectionV1_18 {
pub block_light: Option<fastnbt::ByteArray>, pub block_light: Option<fastnbt::ByteArray>,
} }
/// Version-specific part of a pre-1.18 [Section](SectionOld) /// Version-specific part of a pre-1.18 [Section](SectionV0)
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum SectionOldVariants { pub enum SectionV0Variants {
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
V1_13 { V1_13 {
block_states: fastnbt::LongArray, block_states: fastnbt::LongArray,
palette: Vec<BlockStatePaletteEntry>, palette: Vec<BlockStatePaletteEntry>,
}, },
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
Old { V0 {
blocks: fastnbt::ByteArray, blocks: fastnbt::ByteArray,
data: fastnbt::ByteArray, data: fastnbt::ByteArray,
}, },
Empty {}, Empty {},
} }
/// Pre-1.18 section element found in the [Level](LevelOld) compound /// Pre-1.18 section element found in the [Level](LevelV0) compound
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
pub struct SectionOld { pub struct SectionV0 {
pub y: i8, pub y: i8,
pub block_light: Option<fastnbt::ByteArray>, pub block_light: Option<fastnbt::ByteArray>,
#[serde(flatten)] #[serde(flatten)]
pub section: SectionOldVariants, pub section: SectionV0Variants,
} }
/// Pre-1.18 biome fields found in the [Level](LevelOld) compound /// Pre-1.18 biome fields found in the [Level](LevelV0) compound
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum BiomesOld { pub enum BiomesV0 {
IntArray(fastnbt::IntArray), IntArray(fastnbt::IntArray),
ByteArray(fastnbt::ByteArray), ByteArray(fastnbt::ByteArray),
} }
@ -72,10 +72,10 @@ pub enum BiomesOld {
/// `Level` compound element found in pre-1.18 [chunks](Chunk) /// `Level` compound element found in pre-1.18 [chunks](Chunk)
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
pub struct LevelOld { pub struct LevelV0 {
#[serde(default)] #[serde(default)]
pub sections: Vec<SectionOld>, pub sections: Vec<SectionV0>,
pub biomes: Option<BiomesOld>, pub biomes: Option<BiomesV0>,
} }
/// Version-specific part of a [Chunk] compound /// Version-specific part of a [Chunk] compound
@ -86,8 +86,8 @@ pub enum ChunkVariants {
sections: Vec<SectionV1_18>, sections: Vec<SectionV1_18>,
}, },
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
Old { V0 {
level: LevelOld, level: LevelV0,
}, },
} }

View file

@ -21,7 +21,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option<u8> {
Some(bits) Some(bits)
} }
/// Trait for common functions of [PaletteSection] and [OldSection] /// Trait for common functions of [SectionV1_13] and [SectionV0]
pub trait Section { pub trait Section {
fn get_block_id(&self, coords: BlockCoords) -> Result<&str>; fn get_block_id(&self, coords: BlockCoords) -> Result<&str>;
} }
@ -32,14 +32,14 @@ pub trait Section {
/// the biomes laid out as an array of indices into a palette, similar to the /// the biomes laid out as an array of indices into a palette, similar to the
/// v1.13+ block data. /// v1.13+ block data.
#[derive(Debug)] #[derive(Debug)]
pub struct PaletteSectionBiomes<'a> { pub struct BiomesV18<'a> {
_biomes: Option<&'a fastnbt::LongArray>, _biomes: Option<&'a fastnbt::LongArray>,
_palette: &'a Vec<String>, _palette: &'a Vec<String>,
_bits: u8, _bits: u8,
} }
impl<'a> PaletteSectionBiomes<'a> { impl<'a> BiomesV18<'a> {
/// Constructs a new [PaletteSectionBiomes] from deserialized data structures /// Constructs a new [BiomesV18] from deserialized data structures
pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec<String>) -> Result<Self> { pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec<String>) -> Result<Self> {
let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?;
@ -51,7 +51,7 @@ impl<'a> PaletteSectionBiomes<'a> {
} }
} }
Ok(PaletteSectionBiomes { Ok(BiomesV18 {
_biomes: biomes, _biomes: biomes,
_palette: palette, _palette: palette,
_bits: bits, _bits: bits,
@ -61,15 +61,15 @@ impl<'a> PaletteSectionBiomes<'a> {
/// Minecraft v1.13+ section block data /// Minecraft v1.13+ section block data
#[derive(Debug)] #[derive(Debug)]
pub struct PaletteSection<'a> { pub struct SectionV1_13<'a> {
block_states: Option<&'a fastnbt::LongArray>, block_states: Option<&'a fastnbt::LongArray>,
palette: &'a Vec<de::BlockStatePaletteEntry>, palette: &'a Vec<de::BlockStatePaletteEntry>,
bits: u8, bits: u8,
aligned_blocks: bool, aligned_blocks: bool,
} }
impl<'a> PaletteSection<'a> { impl<'a> SectionV1_13<'a> {
/// Constructs a new [PaletteSection] from deserialized data structures /// Constructs a new [SectionV1_13] from deserialized data structures
pub fn new( pub fn new(
data_version: u32, data_version: u32,
block_states: Option<&'a fastnbt::LongArray>, block_states: Option<&'a fastnbt::LongArray>,
@ -131,7 +131,7 @@ impl<'a> PaletteSection<'a> {
} }
} }
impl<'a> Section for PaletteSection<'a> { impl<'a> Section for SectionV1_13<'a> {
fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { fn get_block_id(&self, coords: BlockCoords) -> Result<&str> {
let index = self.get_palette_index(coords); let index = self.get_palette_index(coords);
let entry = self let entry = self
@ -144,13 +144,13 @@ impl<'a> Section for PaletteSection<'a> {
/// Pre-1.13 section block data /// Pre-1.13 section block data
#[derive(Debug)] #[derive(Debug)]
pub struct OldSection<'a> { pub struct SectionV0<'a> {
blocks: &'a fastnbt::ByteArray, blocks: &'a fastnbt::ByteArray,
data: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray,
} }
impl<'a> OldSection<'a> { impl<'a> SectionV0<'a> {
/// Constructs a new [OldSection] from deserialized data structures /// Constructs a new [SectionV0] from deserialized data structures
pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result<Self> { pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result<Self> {
use BLOCKS_PER_CHUNK as N; use BLOCKS_PER_CHUNK as N;
@ -161,11 +161,11 @@ impl<'a> OldSection<'a> {
bail!("Invalid section extra data"); bail!("Invalid section extra data");
} }
Ok(OldSection { blocks, data }) Ok(SectionV0 { blocks, data })
} }
} }
impl<'a> Section for OldSection<'a> { impl<'a> Section for SectionV0<'a> {
fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { fn get_block_id(&self, coords: BlockCoords) -> Result<&str> {
let offset = coords.offset(); let offset = coords.offset();
let block = self.blocks[offset] as u8; let block = self.blocks[offset] as u8;