From 3a796325ba5c03f43aeebcf9f185f2d892084aec Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 12:53:05 +0100 Subject: [PATCH 001/152] Update dependencies --- Cargo.lock | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7b6072..ab7a97a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.13" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" +checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" dependencies = [ "clap_builder", "clap_derive", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.12" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" +checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" dependencies = [ "anstream", "anstyle", @@ -231,34 +231,28 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "either" @@ -473,15 +467,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libz-ng-sys" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dd9f43e75536a46ee0f92b758f6b63846e594e86638c61a9251338a65baea63" +checksum = "81157dde2fd4ad2b45ea3a4bb47b8193b52a6346b678840d91d80d3c2cd166c5" dependencies = [ "cmake", "libc", @@ -713,9 +707,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -784,9 +778,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -802,9 +796,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", From 5273e4b36656db49e86b9cba8563650a4ecfe224 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 12:59:37 +0100 Subject: [PATCH 002/152] CHANGELOG.md: reformat previous release changes Use the "Added" and "Changed" headings like in previous releases. --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f45c64..2546290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,14 @@ ## [2.0.2] - 2024-01-07 -### Updated +### Added - Added support for Minecraft 1.20.3+ Minecraft 1.20.3 renamed the `grass` block type to `short_grass`. + +### Changed + - Updated [Leaflet](https://leafletjs.com/) to 1.9.4 - Updated attribution URL to https://github.com/neocturne/MinedMap From 1e41e1bc6a89bd0ad9c83224e5d52f34c86060db Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 12:16:12 +0100 Subject: [PATCH 003/152] world/chunk: move SectionIter structs to impl --- src/world/chunk.rs | 66 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 77a543c..e52c27b 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -50,39 +50,6 @@ pub enum Chunk<'a> { Empty, } -/// Inner data structure of [SectionIter] -#[derive(Debug, Clone)] -enum SectionIterInner<'a> { - /// Iterator over sections of [Chunk::V1_18] - V1_18 { - /// Inner iterator into section map - iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, - }, - /// Iterator over sections of [Chunk::V1_13] - V1_13 { - /// Inner iterator into section map - iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, - /// Chunk biome data - biomes: &'a BiomesV0<'a>, - }, - /// Iterator over sections of [Chunk::V0] - V0 { - /// Inner iterator into section map - iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, - /// Chunk biome data - biomes: &'a BiomesV0<'a>, - }, - /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) - Empty, -} - -/// Iterator over the sections of a [Chunk] -#[derive(Debug, Clone)] -pub struct SectionIter<'a> { - /// Inner iterator enum - inner: SectionIterInner<'a>, -} - impl<'a> Chunk<'a> { /// Creates a new [Chunk] from a deserialized [de::Chunk] pub fn new( @@ -283,6 +250,39 @@ impl<'a, T> SectionIterTrait<'a> for T where { } +/// Inner data structure of [SectionIter] +#[derive(Debug, Clone)] +enum SectionIterInner<'a> { + /// Iterator over sections of [Chunk::V1_18] + V1_18 { + /// Inner iterator into section map + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, + }, + /// Iterator over sections of [Chunk::V1_13] + V1_13 { + /// Inner iterator into section map + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, + /// Chunk biome data + biomes: &'a BiomesV0<'a>, + }, + /// Iterator over sections of [Chunk::V0] + V0 { + /// Inner iterator into section map + iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, + /// Chunk biome data + biomes: &'a BiomesV0<'a>, + }, + /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) + Empty, +} + +/// Iterator over the sections of a [Chunk] +#[derive(Debug, Clone)] +pub struct SectionIter<'a> { + /// Inner iterator enum + inner: SectionIterInner<'a>, +} + impl<'a> SectionIter<'a> { /// Helper to run a closure on the inner section iterator fn with_iter(&mut self, f: F) -> T From e8165aa47d4c3523ff4c95d8664ba6642ac0284e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 12:48:34 +0100 Subject: [PATCH 004/152] world: hide unknown block/biome type warnings by default While using MinedMap with modded Minecraft version is not officially supported, it should still work reasonably well if you're okay with custom block types being invisible and custom biomes using default grass/color/foliage colors. Avoid spamming the log with messages for each section in this case without --verbose, and instead just print a single warning at the end of processing. --- CHANGELOG.md | 6 +++ src/core/region_processor.rs | 43 ++++++++++++++-- src/world/chunk.rs | 95 ++++++++++++++++++------------------ src/world/section.rs | 44 +++++++++++------ 4 files changed, 120 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2546290..fccf759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] - ReleaseDate +### Changed + +- Without `--verbose`, only a single warning is printed at the end of + processing for unknown block/biome types, rather than once for every + section where such a block/biome is encountered. + ## [2.0.2] - 2024-01-07 ### Added diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 9e1bb65..0a8ad0e 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,6 +1,14 @@ //! The [RegionProcessor] and related functions -use std::{ffi::OsStr, path::PathBuf, sync::mpsc, time::SystemTime}; +use std::{ + ffi::OsStr, + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc, + }, + time::SystemTime, +}; use anyhow::{Context, Result}; use rayon::prelude::*; @@ -32,6 +40,8 @@ fn parse_region_filename(file_name: &OsStr) -> Option { enum RegionProcessorStatus { /// Region was processed Ok, + /// Region was processed, unknown blocks or biomes were encountered + OkWithUnknown, /// Region was unchanged and skipped Skipped, /// Reading the region failed, previous processed data is reused @@ -68,6 +78,8 @@ struct SingleRegionProcessor<'a> { processed_region: ProcessedRegion, /// Lightmap intermediate data lightmap: image::GrayAlphaImage, + /// True if any unknown block or biome types were encountered during processing + has_unknown: bool, } impl<'a> SingleRegionProcessor<'a> { @@ -104,6 +116,7 @@ impl<'a> SingleRegionProcessor<'a> { lightmap_needed, processed_region, lightmap, + has_unknown: false, }) } @@ -162,8 +175,10 @@ impl<'a> SingleRegionProcessor<'a> { /// Processes a single chunk fn process_chunk(&mut self, chunk_coords: ChunkCoords, data: world::de::Chunk) -> Result<()> { - let chunk = world::chunk::Chunk::new(&data, self.block_types, self.biome_types) - .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; + let (chunk, has_unknown) = + world::chunk::Chunk::new(&data, self.block_types, self.biome_types) + .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; + self.has_unknown |= has_unknown; let Some(layer::LayerData { blocks, biomes, @@ -231,7 +246,11 @@ impl<'a> SingleRegionProcessor<'a> { self.save_region()?; self.save_lightmap()?; - Ok(RegionProcessorStatus::Ok) + Ok(if self.has_unknown { + RegionProcessorStatus::OkWithUnknown + } else { + RegionProcessorStatus::Ok + }) } } @@ -300,6 +319,8 @@ impl<'a> RegionProcessor<'a> { let (processed_send, processed_recv) = mpsc::channel(); let (error_send, error_recv) = mpsc::channel(); + let has_unknown = AtomicBool::new(false); + self.collect_regions()?.par_iter().try_for_each(|&coords| { let ret = self .process_region(coords) @@ -311,6 +332,10 @@ impl<'a> RegionProcessor<'a> { match ret { RegionProcessorStatus::Ok => processed_send.send(()).unwrap(), + RegionProcessorStatus::OkWithUnknown => { + has_unknown.store(true, Ordering::Relaxed); + processed_send.send(()).unwrap(); + } RegionProcessorStatus::Skipped => {} RegionProcessorStatus::ErrorOk | RegionProcessorStatus::ErrorMissing => { error_send.send(()).unwrap() @@ -335,6 +360,16 @@ impl<'a> RegionProcessor<'a> { errors, ); + if has_unknown.into_inner() { + warn!("Unknown block or biome types found during processing"); + eprint!(concat!( + "\n", + " If you're encountering this issue with an unmodified Minecraft version supported by MinedMap,\n", + " please file a bug report including the output with the --verbose flag.\n", + "\n", + )); + } + // Sort regions in a zig-zag pattern to optimize cache usage regions.sort_unstable_by_key(|&TileCoords { x, z }| (x, if x % 2 == 0 { z } else { -z })); diff --git a/src/world/chunk.rs b/src/world/chunk.rs index e52c27b..993a79e 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -56,7 +56,7 @@ impl<'a> Chunk<'a> { data: &'a de::Chunk, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result { + ) -> Result<(Self, bool)> { let data_version = data.data_version.unwrap_or_default(); match &data.chunk { @@ -75,8 +75,9 @@ impl<'a> Chunk<'a> { sections: &'a Vec, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result { + ) -> Result<(Self, bool)> { let mut section_map = BTreeMap::new(); + let mut has_unknown = false; for section in sections { match §ion.section { @@ -85,22 +86,27 @@ impl<'a> Chunk<'a> { biomes, block_light, } => { + let (loaded_section, unknown_blocks) = SectionV1_13::new( + data_version, + block_states.data.as_deref(), + &block_states.palette, + block_types, + ) + .with_context(|| format!("Failed to load section at Y={}", section.y))?; + has_unknown |= unknown_blocks; + + let (loaded_biomes, unknown_biomes) = + BiomesV1_18::new(biomes.data.as_deref(), &biomes.palette, biome_types) + .with_context(|| { + format!("Failed to load section biomes at Y={}", section.y) + })?; + has_unknown |= unknown_biomes; + section_map.insert( SectionY(section.y), ( - SectionV1_13::new( - data_version, - block_states.data.as_deref(), - &block_states.palette, - block_types, - ) - .with_context(|| { - format!("Failed to load section at Y={}", section.y) - })?, - BiomesV1_18::new(biomes.data.as_deref(), &biomes.palette, biome_types) - .with_context(|| { - format!("Failed to load section biomes at Y={}", section.y) - })?, + loaded_section, + loaded_biomes, BlockLight::new(block_light.as_deref()).with_context(|| { format!("Failed to load section block light at Y={}", section.y) })?, @@ -111,7 +117,8 @@ impl<'a> Chunk<'a> { }; } - Ok(Chunk::V1_18 { section_map }) + let chunk = Chunk::V1_18 { section_map }; + Ok((chunk, has_unknown)) } /// [Chunk::new] implementation for all pre-1.18 chunk variants @@ -120,9 +127,10 @@ impl<'a> Chunk<'a> { level: &'a de::LevelV0, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result { + ) -> Result<(Self, bool)> { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new(); + let mut has_unknown = false; for section in &level.sections { let block_light = @@ -134,21 +142,13 @@ impl<'a> Chunk<'a> { block_states, palette, } => { - section_map_v1_13.insert( - SectionY(section.y.into()), - ( - SectionV1_13::new( - data_version, - Some(block_states), - palette, - block_types, - ) - .with_context(|| { - format!("Failed to load section at Y={}", section.y) - })?, - block_light, - ), - ); + let (loaded_section, unknown_blocks) = + SectionV1_13::new(data_version, Some(block_states), palette, block_types) + .with_context(|| format!("Failed to load section at Y={}", section.y))?; + has_unknown |= unknown_blocks; + + section_map_v1_13 + .insert(SectionY(section.y.into()), (loaded_section, block_light)); } de::SectionV0Variant::V0 { blocks, data } => { section_map_v0.insert( @@ -166,23 +166,22 @@ impl<'a> Chunk<'a> { } let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types); - - Ok( - match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { - (true, true) => Chunk::Empty, - (false, true) => Chunk::V1_13 { - section_map: section_map_v1_13, - biomes: biomes?, - }, - (true, false) => Chunk::V0 { - section_map: section_map_v0, - biomes: biomes?, - }, - (false, false) => { - bail!("Mixed section versions"); - } + let chunk = match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { + (true, true) => Chunk::Empty, + (false, true) => Chunk::V1_13 { + section_map: section_map_v1_13, + biomes: biomes?, }, - ) + (true, false) => Chunk::V0 { + section_map: section_map_v0, + biomes: biomes?, + }, + (false, false) => { + bail!("Mixed section versions"); + } + }; + + Ok((chunk, has_unknown)) } /// Returns true if the chunk does not contain any sections diff --git a/src/world/section.rs b/src/world/section.rs index 998d2f7..97e0061 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -7,7 +7,7 @@ use std::fmt::Debug; use anyhow::{bail, Context, Result}; use num_integer::div_rem; -use tracing::warn; +use tracing::debug; use super::de; use crate::{ @@ -73,7 +73,7 @@ impl<'a> SectionV1_13<'a> { block_states: Option<&'a [i64]>, palette: &'a [de::BlockStatePaletteEntry], block_types: &'a BlockTypes, - ) -> Result { + ) -> Result<(Self, bool)> { let aligned_blocks = data_version >= 2529; let bits = palette_bits(palette.len(), 4, 12).context("Unsupported block palette size")?; @@ -90,23 +90,29 @@ impl<'a> SectionV1_13<'a> { } } + let mut has_unknown = false; + let palette_types = palette .iter() .map(|entry| { let block_type = block_types.get(&entry.name); if block_type.is_none() { - warn!("Unknown block type: {}", entry.name); + debug!("Unknown block type: {}", entry.name); + has_unknown = true; } block_type }) .collect(); - Ok(Self { - block_states, - palette: palette_types, - bits, - aligned_blocks, - }) + Ok(( + Self { + block_states, + palette: palette_types, + bits, + aligned_blocks, + }, + has_unknown, + )) } /// Looks up the block type palette index at the given coordinates @@ -231,7 +237,7 @@ impl<'a> BiomesV1_18<'a> { biomes: Option<&'a [i64]>, palette: &'a [String], biome_types: &'a BiomeTypes, - ) -> Result { + ) -> Result<(Self, bool)> { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; if let Some(biomes) = biomes { @@ -242,22 +248,28 @@ impl<'a> BiomesV1_18<'a> { } } + let mut has_unknown = false; + let palette_types = palette .iter() .map(|entry| { let biome_type = biome_types.get(entry); if biome_type.is_none() { - warn!("Unknown biome type: {}", entry); + debug!("Unknown biome type: {}", entry); + has_unknown = true; } biome_type }) .collect(); - Ok(BiomesV1_18 { - biomes, - palette: palette_types, - bits, - }) + Ok(( + BiomesV1_18 { + biomes, + palette: palette_types, + bits, + }, + has_unknown, + )) } /// Looks up the block type palette index at the given coordinates From 2e6a200c6c9936fd731abfae9b5d7de10092ee03 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 22:07:20 +0100 Subject: [PATCH 005/152] README.md: reference screenshot by commit ID --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9191910..a2b98e0 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ * Typically uses less than 100MB of RAM in single-threaded operation (may be higher when `-j` is passed) * Cross-platform: runs on Linux, Windows, and likely other systems like MacOS as well -![Screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/main/docs/images/MinedMap.png) +![Screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/997a4fb24e89d2cd3c671d77eafaa47084d14304/docs/images/MinedMap.png) ## How to use From 7b12c4aea3260d89d3694e18fa68ebf14cb45223 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 22:40:53 +0100 Subject: [PATCH 006/152] README.md: some improvements to the "How to use" and "Installation" sections --- README.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a2b98e0..be09c47 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ![Screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/997a4fb24e89d2cd3c671d77eafaa47084d14304/docs/images/MinedMap.png) -## How to use +## About MinedMap consists of two components: a map renderer generating map tiles from Minecraft save games, and a viewer for displaying and navigating maps in a browser @@ -20,16 +20,16 @@ based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired [MapRend](https://github.com/YSelfTool/MapRend), but has been reimplemented from scratch (first in C++, now in Rust) for highest performance. -The viewer expects the the map data in a directory named `data`. To generate a new -map, create this empty directory inside the viewer directory. Next, to generate the -map files run MinedMap passing the source and the destination paths on the command -line: +## How to use + +Minecraft stores its save data in a directory `~/.minecraft/saves` on Linux, +and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate minedmap +tile data from a save game called "World", use the a command like the following +(replacing the first argument with the path to your save data; `viewer` refers +to the directory where you unpacked the MinedMap viewer): ```shell -minedmap /path/to/save/game /path/to/viewer/data +minedmap ~/.minecraft/saves/World viewer/data ``` -The save game is stored in `saves` inside your Minecraft main directory -(`~/.minecraft` on Linux, `C:\Users\\AppData\Roaming\.minecraft` on Windows) -in a subdirectory with the name of your world. The first map generation might take a while for big worlds, but subsequent calls will only rebuild tiles for region files that have changed, rarely taking more than a second @@ -38,7 +38,8 @@ MinedMap as a Cron job every minute. Note that it is not possible to open the viewer *index.html* without a webserver, as it cannot load the generated map information from `file://` URIs. For testing purposes, -you can use a minimal HTTP server, e.g. (if you have Python installed): +you can use a minimal HTTP server, e.g. if you have Python installed just run the +following in the viewer directory: ```shell python3 -m http.server ``` @@ -48,7 +49,10 @@ the generated map files to public webspace to make the map available to others. ## Installation -Building the MinedMap map generator from source requires a recent Rust toolchain (1.72.0 +Binary builds of the map generator for Linux and Windows, as well as an archive +containing the viewer can be found on the GitHub release page. + +Building the generator from source requires a recent Rust toolchain (1.72.0 or newer). The following command can be used to build the current development version: ```shell cargo install --git 'https://github.com/neocturne/MinedMap.git' From e5d9c813ba3118d04dc7e52e3dc6f48808a69120 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 22:55:42 +0100 Subject: [PATCH 007/152] docs/images: add screenshot for sign marker documentation --- docs/images/signs.png | Bin 0 -> 92020 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/signs.png diff --git a/docs/images/signs.png b/docs/images/signs.png new file mode 100644 index 0000000000000000000000000000000000000000..d1d644d8be2ef6d53b07c6e67636b676f6fd8110 GIT binary patch literal 92020 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 Date: Mon, 8 Jan 2024 02:34:39 +0100 Subject: [PATCH 008/152] core/common: add better explanation to file meta version definitions --- src/core/common.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/common.rs b/src/core/common.rs index 39c8e54..d17056f 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -14,12 +14,21 @@ use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; /// Increase to force regeneration of all output files /// MinedMap processed region data version number +/// +/// Increase when the generation of processed regions from region data changes +/// (usually because of updated resource data) pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap map tile data version number +/// +/// Increase when the generation of map tiles from processed regions changes +/// (because of code changes in tile generation) pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap lightmap data version number +/// +/// Increase when the generation of lightmap tiles from region data changes +/// (usually because of updated resource data) pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// Coordinate pair of a generated tile From 0988ebe0951ddeee43c693099a41ab18985b57ce Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 8 Jan 2024 02:35:05 +0100 Subject: [PATCH 009/152] core/tile_mipmapper: fix file meta version for mipmap tiles The meta version should only change when the outputs must be regenerated even if the inputs stay the same. This should never be the case for mipmap tiles, so we separate the meta version from map/lightmap tiles. --- src/core/common.rs | 5 +++++ src/core/tile_mipmapper.rs | 21 +++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index d17056f..49c8301 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -31,6 +31,11 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// (usually because of updated resource data) pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +/// MinedMap mipmap data version number +/// +/// Increase when the mipmap generation changes (this should not happen) +pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + /// Coordinate pair of a generated tile /// /// Each tile corresponds to one Minecraft region file diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index 355bd23..6ea8750 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -70,12 +70,8 @@ impl<'a> TileMipmapper<'a> { /// Tile width/height const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - let version = match kind { - TileKind::Map => REGION_FILE_META_VERSION, - TileKind::Lightmap => LIGHTMAP_FILE_META_VERSION, - }; let output_path = self.config.tile_path(kind, level, coords); - let output_timestamp = fs::read_timestamp(&output_path, version); + let output_timestamp = fs::read_timestamp(&output_path, MIPMAP_FILE_META_VERSION); let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] .into_iter() @@ -149,11 +145,16 @@ impl<'a> TileMipmapper<'a> { ); } - fs::create_with_timestamp(&output_path, version, input_timestamp, |file| { - image - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - })?; + fs::create_with_timestamp( + &output_path, + MIPMAP_FILE_META_VERSION, + input_timestamp, + |file| { + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }, + )?; count_processed.send(()).unwrap(); Ok(()) From f78dd795ca87d12c8299a876cebc7ee6c8079bb9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 24 Nov 2023 19:30:45 +0100 Subject: [PATCH 010/152] 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; From 61d456846aee3beaad5a77fb0f9fbf5da351eeab Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 12:08:52 +0100 Subject: [PATCH 011/152] world: implement decoding raw JSON text into a linear list of formatted strings --- src/world/json_text.rs | 150 ++++++++++++++++++++++++++++++++++++++++- src/world/mod.rs | 1 + src/world/sign.rs | 88 ++++++++++++++++++++++++ 3 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/world/sign.rs diff --git a/src/world/json_text.rs b/src/world/json_text.rs index 561725f..8e53ead 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -1,7 +1,155 @@ //! Newtype and helper methods for handling Minecraft Raw JSON Text +use std::{collections::VecDeque, sync::Arc}; + use serde::Deserialize; +/// A span of formatted text +/// +/// A [JSONText] consists of a tree of [FormattedText] nodes (canonically +/// represented as a [FormattedTextTree], but other kinds are possible with +/// is handled by [DeserializedText]. +/// +/// Formatting that is not set in a node is inherited from the parent. +#[derive(Debug, Deserialize, Default)] +pub struct FormattedText { + #[serde(default)] + /// Text content + pub text: String, + /// Text color + pub color: Option>, + /// Bold formatting + pub bold: Option, + /// Italic formatting + pub italic: Option, + /// Underlines formatting + pub underlined: Option, + /// Strikethrough formatting + pub strikethrough: Option, + /// Obfuscated formatting + pub obfuscated: Option, +} + +impl FormattedText { + /// Fills in unset formatting fields from a parent node + pub fn inherit(self, parent: &Self) -> Self { + FormattedText { + text: self.text, + color: self.color.or_else(|| parent.color.clone()), + bold: self.bold.or(parent.bold), + italic: self.italic.or(parent.italic), + underlined: self.underlined.or(parent.underlined), + strikethrough: self.strikethrough.or(parent.strikethrough), + obfuscated: self.obfuscated.or(parent.obfuscated), + } + } +} + +/// A tree of [FormattedText] nodes +/// +/// Each node including the root has a `text` and a list of children (`extra`). +#[derive(Debug, Deserialize, Default)] +pub struct FormattedTextTree { + /// Root node content + #[serde(flatten)] + text: FormattedText, + /// List of child trees + #[serde(default)] + extra: VecDeque, +} + +impl From for FormattedTextTree { + fn from(value: String) -> Self { + FormattedTextTree { + text: FormattedText { + text: value, + ..Default::default() + }, + extra: VecDeque::new(), + } + } +} + +/// List of [FormattedText] +#[derive(Debug)] +pub struct FormattedTextList(pub Vec); + +impl FormattedTextList { + /// Returns `true` when [FormattedTextList] does not contain any text + pub fn is_empty(&self) -> bool { + self.0.iter().all(|text| text.text.is_empty()) + } +} + +/// Raw deserialized [JSONText] +/// +/// A [JSONText] can contain various different JSON types. +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum DeserializedText { + /// Unformatted string + String(String), + /// Unformatted number (will be converted to a string) + Number(f32), + /// Unformatted boolean (will be converted to a string) + Boolean(bool), + /// List of [DeserializedText] + /// + /// The tail elements are appended as children of the head element. + List(VecDeque), + /// The canonical [FormattedTextTree] structure + Object(FormattedTextTree), +} + +impl DeserializedText { + /// Converts a [DeserializedText] into the regular [FormattedTextTree] format + /// + /// Most variants are simply converted to strings. A list is handled by + /// appending all tail elements to the `extra` field of the head. + pub fn canonicalize(self) -> FormattedTextTree { + match self { + DeserializedText::Object(obj) => obj, + DeserializedText::String(s) => FormattedTextTree::from(s), + DeserializedText::Number(n) => FormattedTextTree::from(n.to_string()), + DeserializedText::Boolean(b) => FormattedTextTree::from(b.to_string()), + DeserializedText::List(mut list) => { + let mut obj = list + .pop_front() + .map(|t| t.canonicalize()) + .unwrap_or_default(); + obj.extra.append(&mut list); + obj + } + } + } + + /// Converts the tree of [FormattedText] nodes into a linear list by + /// copying formatting flags into each node. + pub fn linearize(self, parent: &FormattedText) -> FormattedTextList { + let obj = self.canonicalize(); + let mut ret = vec![obj.text.inherit(parent)]; + + for extra in obj.extra { + ret.append(&mut extra.linearize(&ret[0]).0); + } + + FormattedTextList(ret) + } +} + +impl Default for DeserializedText { + fn default() -> Self { + DeserializedText::Object(FormattedTextTree::from(String::new())) + } +} + /// Minecraft Raw JSON Text #[derive(Debug, Deserialize)] -pub struct JSONText(String); +pub struct JSONText(pub String); + +impl JSONText { + /// Deserializes a [JSONText] into a [DeserializedText] + pub fn deserialize(&self) -> DeserializedText { + serde_json::from_str(&self.0).unwrap_or_default() + } +} diff --git a/src/world/mod.rs b/src/world/mod.rs index e3c52ba..38d5174 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -5,3 +5,4 @@ pub mod de; pub mod json_text; pub mod layer; pub mod section; +pub mod sign; diff --git a/src/world/sign.rs b/src/world/sign.rs new file mode 100644 index 0000000..c13eebe --- /dev/null +++ b/src/world/sign.rs @@ -0,0 +1,88 @@ +//! Processing of sign text + +use std::sync::Arc; + +use super::{ + de, + json_text::{FormattedText, FormattedTextList, JSONText}, +}; + +/// Version-independent reference to (front or back) sign text +#[derive(Debug, Default)] +pub struct RawSignText<'a> { + /// Lines of sign text + /// + /// A regular sign always has 4 lines of text. The back of pre-1.20 + /// signs is represented as a [SignText] without any `messages`. + pub messages: Vec<&'a JSONText>, + /// Sign color + /// + /// Defaults to "black". + pub color: Option<&'a str>, +} + +impl<'a> RawSignText<'a> { + /// Decodes the [RawSignText] into a [SignText] + pub fn decode(&self) -> SignText { + let color = self.color.map(|c| Arc::new(c.to_owned())); + let parent = FormattedText { + color, + ..Default::default() + }; + SignText( + self.messages + .iter() + .map(|message| message.deserialize().linearize(&parent)) + .collect(), + ) + } +} + +impl<'a> From<&'a de::BlockEntitySignV1_20Text> for RawSignText<'a> { + fn from(value: &'a de::BlockEntitySignV1_20Text) -> Self { + RawSignText { + messages: value.messages.iter().collect(), + color: value.color.as_deref(), + } + } +} + +/// Helper methods for [de::BlockEntitySign] +pub trait BlockEntitySignExt { + /// Returns the front and back text of a sign in a version-indepentent format + fn text(&self) -> (RawSignText, RawSignText); +} + +impl BlockEntitySignExt for de::BlockEntitySign { + fn text(&self) -> (RawSignText, RawSignText) { + match self { + de::BlockEntitySign::V0 { + text1, + text2, + text3, + text4, + color, + } => ( + RawSignText { + messages: vec![text1, text2, text3, text4], + color: color.as_deref(), + }, + Default::default(), + ), + de::BlockEntitySign::V1_20 { + front_text, + back_text, + } => (front_text.into(), back_text.into()), + } + } +} + +/// Deserialized and linearized sign text +pub struct SignText(pub Vec); + +impl SignText { + /// Checks if all lines of the sign text are empty + pub fn is_empty(&self) -> bool { + self.0.iter().all(|line| line.is_empty()) + } +} From 638d5046c989f4937c27e1d648b06be328f49242 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 19:07:49 +0100 Subject: [PATCH 012/152] world/chunk: change Chunk into a struct The version-specific part is extracted as an enum ChunkInner. --- src/world/chunk.rs | 63 ++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index cd3bf4f..e3ba58a 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -16,10 +16,9 @@ use crate::{ types::*, }; -/// Chunk data structure wrapping a [de::Chunk] for convenient access to -/// block and biome data +/// Version-specific part of [Chunk] #[derive(Debug)] -pub enum Chunk<'a> { +pub enum ChunkInner<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { /// Section data @@ -50,6 +49,14 @@ pub enum Chunk<'a> { Empty, } +/// Chunk data structure wrapping a [de::Chunk] for convenient access to +/// block and biome data +#[derive(Debug)] +pub struct Chunk<'a> { + /// Version-specific data + inner: ChunkInner<'a>, +} + impl<'a> Chunk<'a> { /// Creates a new [Chunk] from a deserialized [de::Chunk] pub fn new( @@ -59,15 +66,17 @@ impl<'a> Chunk<'a> { ) -> Result<(Self, bool)> { let data_version = data.data_version.unwrap_or_default(); - match &data.chunk { + let (inner, has_unknown) = match &data.chunk { de::ChunkVariant::V1_18 { sections, block_entities: _, - } => Self::new_v1_18(data_version, sections, block_types, biome_types), + } => 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) + Self::new_v0(data_version, level, block_types, biome_types)? } - } + }; + + Ok((Chunk { inner }, has_unknown)) } /// [Chunk::new] implementation for Minecraft v1.18+ chunks @@ -76,7 +85,7 @@ impl<'a> Chunk<'a> { sections: &'a Vec, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result<(Self, bool)> { + ) -> Result<(ChunkInner<'a>, bool)> { let mut section_map = BTreeMap::new(); let mut has_unknown = false; @@ -118,7 +127,7 @@ impl<'a> Chunk<'a> { }; } - let chunk = Chunk::V1_18 { section_map }; + let chunk = ChunkInner::V1_18 { section_map }; Ok((chunk, has_unknown)) } @@ -128,7 +137,7 @@ impl<'a> Chunk<'a> { level: &'a de::LevelV0, block_types: &'a BlockTypes, biome_types: &'a BiomeTypes, - ) -> Result<(Self, bool)> { + ) -> Result<(ChunkInner<'a>, bool)> { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new(); let mut has_unknown = false; @@ -168,12 +177,12 @@ impl<'a> Chunk<'a> { let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types); let chunk = match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { - (true, true) => Chunk::Empty, - (false, true) => Chunk::V1_13 { + (true, true) => ChunkInner::Empty, + (false, true) => ChunkInner::V1_13 { section_map: section_map_v1_13, biomes: biomes?, }, - (true, false) => Chunk::V0 { + (true, false) => ChunkInner::V0 { section_map: section_map_v0, biomes: biomes?, }, @@ -187,11 +196,11 @@ impl<'a> Chunk<'a> { /// Returns true if the chunk does not contain any sections pub fn is_empty(&self) -> bool { - match self { - Chunk::V1_18 { section_map } => section_map.is_empty(), - Chunk::V1_13 { section_map, .. } => section_map.is_empty(), - Chunk::V0 { section_map, .. } => section_map.is_empty(), - Chunk::Empty => true, + match &self.inner { + ChunkInner::V1_18 { section_map } => section_map.is_empty(), + ChunkInner::V1_13 { section_map, .. } => section_map.is_empty(), + ChunkInner::V0 { section_map, .. } => section_map.is_empty(), + ChunkInner::Empty => true, } } @@ -199,25 +208,25 @@ impl<'a> Chunk<'a> { pub fn sections(&self) -> SectionIter { use SectionIterInner::*; SectionIter { - inner: match self { - Chunk::V1_18 { section_map } => V1_18 { + inner: match &self.inner { + ChunkInner::V1_18 { section_map } => V1_18 { iter: section_map.iter(), }, - Chunk::V1_13 { + ChunkInner::V1_13 { section_map, biomes, } => V1_13 { iter: section_map.iter(), biomes, }, - Chunk::V0 { + ChunkInner::V0 { section_map, biomes, } => V0 { iter: section_map.iter(), biomes, }, - Chunk::Empty => Empty, + ChunkInner::Empty => Empty, }, } } @@ -253,26 +262,26 @@ impl<'a, T> SectionIterTrait<'a> for T where /// Inner data structure of [SectionIter] #[derive(Debug, Clone)] enum SectionIterInner<'a> { - /// Iterator over sections of [Chunk::V1_18] + /// Iterator over sections of [ChunkInner::V1_18] V1_18 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, }, - /// Iterator over sections of [Chunk::V1_13] + /// Iterator over sections of [ChunkInner::V1_13] V1_13 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, /// Chunk biome data biomes: &'a BiomesV0<'a>, }, - /// Iterator over sections of [Chunk::V0] + /// Iterator over sections of [ChunkInner::V0] V0 { /// Inner iterator into section map iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, /// Chunk biome data biomes: &'a BiomesV0<'a>, }, - /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) + /// Empty iterator over an unpopulated chunk ([ChunkInner::Empty]) Empty, } From f0e0db63d39fb5731483d6c5a93af950de4433e4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 20:34:50 +0100 Subject: [PATCH 013/152] world: process sign data, prepare for serialization --- src/world/block_entity.rs | 89 +++++++++++++++++++++++++++++++++++++++ src/world/chunk.rs | 36 ++++++++++++---- src/world/json_text.rs | 12 ++++-- src/world/mod.rs | 1 + src/world/sign.rs | 3 ++ 5 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/world/block_entity.rs diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs new file mode 100644 index 0000000..65d95e4 --- /dev/null +++ b/src/world/block_entity.rs @@ -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 { + 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, + }) + } +} diff --git a/src/world/chunk.rs b/src/world/chunk.rs index e3ba58a..5a8937e 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -10,7 +10,7 @@ use std::{ use anyhow::{bail, Context, Result}; -use super::{de, section::*}; +use super::{block_entity::BlockEntity, de, section::*}; use crate::{ resource::{BiomeTypes, BlockTypes}, types::*, @@ -55,6 +55,8 @@ pub enum ChunkInner<'a> { pub struct Chunk<'a> { /// Version-specific data inner: ChunkInner<'a>, + /// Unprocessed block entities + block_entities: &'a Vec, } impl<'a> Chunk<'a> { @@ -66,17 +68,27 @@ impl<'a> Chunk<'a> { ) -> Result<(Self, bool)> { 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 { 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)? - } + block_entities, + } => ( + Self::new_v1_18(data_version, sections, 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 @@ -230,6 +242,14 @@ impl<'a> Chunk<'a> { }, } } + + /// Processes all of the chunk's block entities + pub fn block_entities(&self) -> Vec { + self.block_entities + .iter() + .filter_map(BlockEntity::new) + .collect() + } } /// Reference to block, biome and block light data of a section diff --git a/src/world/json_text.rs b/src/world/json_text.rs index 8e53ead..a9c1f13 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -2,7 +2,7 @@ use std::{collections::VecDeque, sync::Arc}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; /// A span of formatted text /// @@ -11,22 +11,28 @@ use serde::Deserialize; /// is handled by [DeserializedText]. /// /// 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 { #[serde(default)] /// Text content pub text: String, /// Text color + #[serde(skip_serializing_if = "Option::is_none")] pub color: Option>, /// Bold formatting + #[serde(skip_serializing_if = "Option::is_none")] pub bold: Option, /// Italic formatting + #[serde(skip_serializing_if = "Option::is_none")] pub italic: Option, /// Underlines formatting + #[serde(skip_serializing_if = "Option::is_none")] pub underlined: Option, /// Strikethrough formatting + #[serde(skip_serializing_if = "Option::is_none")] pub strikethrough: Option, /// Obfuscated formatting + #[serde(skip_serializing_if = "Option::is_none")] pub obfuscated: Option, } @@ -71,7 +77,7 @@ impl From for FormattedTextTree { } /// List of [FormattedText] -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct FormattedTextList(pub Vec); impl FormattedTextList { diff --git a/src/world/mod.rs b/src/world/mod.rs index 38d5174..6426c92 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,5 +1,6 @@ //! Data structures describing Minecraft save data +pub mod block_entity; pub mod chunk; pub mod de; pub mod json_text; diff --git a/src/world/sign.rs b/src/world/sign.rs index c13eebe..e53be87 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -2,6 +2,8 @@ use std::sync::Arc; +use serde::{Deserialize, Serialize}; + use super::{ de, json_text::{FormattedText, FormattedTextList, JSONText}, @@ -77,6 +79,7 @@ impl BlockEntitySignExt for de::BlockEntitySign { } } +#[derive(Debug, Default, Serialize, Deserialize)] /// Deserialized and linearized sign text pub struct SignText(pub Vec); From 5d40d061a40daa8d799552915652744b988a6316 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 12:47:31 +0100 Subject: [PATCH 014/152] io/storage: split out inner part of read/write Allow reusing the read/write logic without requiring control over the file open. --- src/core/region_processor.rs | 2 +- src/core/tile_renderer.rs | 2 +- src/io/storage.rs | 51 ++++++++++++++++++++---------------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 0a8ad0e..04699d3 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -145,7 +145,7 @@ impl<'a> SingleRegionProcessor<'a> { return Ok(()); } - storage::write( + storage::write_file( &self.output_path, &self.processed_region, REGION_FILE_META_VERSION, diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index b341076..ce9fed3 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -105,7 +105,7 @@ impl<'a> TileRenderer<'a> { region_loader .get_or_try_init(|| async { - storage::read(&processed_path).context("Failed to load processed region data") + storage::read_file(&processed_path).context("Failed to load processed region data") }) .await .cloned() diff --git a/src/io/storage.rs b/src/io/storage.rs index 99a8d63..634f082 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -14,43 +14,50 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; +/// Serializes data and writes it to a writer +pub fn write(writer: &mut W, value: &T) -> Result<()> { + let data = bincode::serialize(value)?; + let len = u32::try_from(data.len())?; + let compressed = zstd::bulk::compress(&data, 1)?; + drop(data); + + writer.write_all(&len.to_be_bytes())?; + writer.write_all(&compressed)?; + + Ok(()) +} + /// Serializes data and stores it in a file /// /// A timestamp is stored in an assiciated metadata file. -pub fn write( +pub fn write_file( path: &Path, value: &T, version: fs::FileMetaVersion, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp(path, version, timestamp, |file| { - let data = bincode::serialize(value)?; - let len = u32::try_from(data.len())?; - let compressed = zstd::bulk::compress(&data, 1)?; - drop(data); + fs::create_with_timestamp(path, version, timestamp, |file| write(file, value)) +} - file.write_all(&len.to_be_bytes())?; - file.write_all(&compressed)?; +/// Reads data from a reader and deserializes it +pub fn read(reader: &mut R) -> Result { + let mut len_buf = [0u8; 4]; + reader.read_exact(&mut len_buf)?; + let len = usize::try_from(u32::from_be_bytes(len_buf))?; - Ok(()) - }) + let mut compressed = vec![]; + reader.read_to_end(&mut compressed)?; + let data = zstd::bulk::decompress(&compressed, len)?; + drop(compressed); + + Ok(bincode::deserialize(&data)?) } /// Reads data from a file and deserializes it -pub fn read(path: &Path) -> Result { +pub fn read_file(path: &Path) -> Result { (|| -> Result { let mut file = File::open(path)?; - - let mut len_buf = [0u8; 4]; - file.read_exact(&mut len_buf)?; - let len = usize::try_from(u32::from_be_bytes(len_buf))?; - - let mut compressed = vec![]; - file.read_to_end(&mut compressed)?; - let data = zstd::bulk::decompress(&compressed, len)?; - drop(compressed); - - Ok(bincode::deserialize(&data)?) + read(&mut file) })() .with_context(|| format!("Failed to read file {}", path.display())) } From c44f6ab859bfcc8d10592097d4188db11a9a53a4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 14:12:51 +0100 Subject: [PATCH 015/152] io/storage: add JSON support Bincode can't deal with a number of serde's features that would be desirable if we're using the same Serialize impls for generating JSON data for the viewer. --- src/core/region_processor.rs | 1 + src/core/tile_renderer.rs | 3 ++- src/io/storage.rs | 34 +++++++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 04699d3..52cb165 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -148,6 +148,7 @@ impl<'a> SingleRegionProcessor<'a> { storage::write_file( &self.output_path, &self.processed_region, + storage::Format::Bincode, REGION_FILE_META_VERSION, self.input_timestamp, ) diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index ce9fed3..09ad8a1 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -105,7 +105,8 @@ impl<'a> TileRenderer<'a> { region_loader .get_or_try_init(|| async { - storage::read_file(&processed_path).context("Failed to load processed region data") + storage::read_file(&processed_path, storage::Format::Bincode) + .context("Failed to load processed region data") }) .await .cloned() diff --git a/src/io/storage.rs b/src/io/storage.rs index 634f082..9296166 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -14,9 +14,24 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; +/// Storage format +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Format { + /// Encode as Bincode + /// + /// Bincode is more efficient than JSON, but cannot handle many of + /// serde's features like flatten, conditional skipping, ... + Bincode, + /// Encode as JSON + Json, +} + /// Serializes data and writes it to a writer -pub fn write(writer: &mut W, value: &T) -> Result<()> { - let data = bincode::serialize(value)?; +pub fn write(writer: &mut W, value: &T, format: Format) -> Result<()> { + let data = match format { + Format::Bincode => bincode::serialize(value)?, + Format::Json => serde_json::to_vec(value)?, + }; let len = u32::try_from(data.len())?; let compressed = zstd::bulk::compress(&data, 1)?; drop(data); @@ -33,14 +48,15 @@ pub fn write(writer: &mut W, value: &T) -> Result<()> { pub fn write_file( path: &Path, value: &T, + format: Format, version: fs::FileMetaVersion, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp(path, version, timestamp, |file| write(file, value)) + fs::create_with_timestamp(path, version, timestamp, |file| write(file, value, format)) } /// Reads data from a reader and deserializes it -pub fn read(reader: &mut R) -> Result { +pub fn read(reader: &mut R, format: Format) -> Result { let mut len_buf = [0u8; 4]; reader.read_exact(&mut len_buf)?; let len = usize::try_from(u32::from_be_bytes(len_buf))?; @@ -50,14 +66,18 @@ pub fn read(reader: &mut R) -> Result { let data = zstd::bulk::decompress(&compressed, len)?; drop(compressed); - Ok(bincode::deserialize(&data)?) + let value = match format { + Format::Bincode => bincode::deserialize(&data)?, + Format::Json => serde_json::from_slice(&data)?, + }; + Ok(value) } /// Reads data from a file and deserializes it -pub fn read_file(path: &Path) -> Result { +pub fn read_file(path: &Path, format: Format) -> Result { (|| -> Result { let mut file = File::open(path)?; - read(&mut file) + read(&mut file, format) })() .with_context(|| format!("Failed to read file {}", path.display())) } From 7297c03567e7990520ce9acffe9cb19b517b6ab0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 21:46:55 +0100 Subject: [PATCH 016/152] core/region_processor: store processed block entities for each region --- src/core/common.rs | 39 ++++++++++++++++- src/core/region_processor.rs | 82 ++++++++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 49c8301..cd8fd8f 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -9,7 +9,12 @@ use std::{ use indexmap::IndexSet; use serde::{Deserialize, Serialize}; -use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; +use crate::{ + io::fs::FileMetaVersion, + resource::Biome, + types::*, + world::{block_entity::BlockEntity, layer}, +}; /// Increase to force regeneration of all output files @@ -36,6 +41,11 @@ pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// Increase when the mipmap generation changes (this should not happen) pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +/// MinedMap processed entity data version number +/// +/// Increase when entity collection changes bacause of code changes. +pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + /// Coordinate pair of a generated tile /// /// Each tile corresponds to one Minecraft region file @@ -94,6 +104,13 @@ pub struct ProcessedRegion { pub chunks: ChunkArray>>, } +/// Data structure for storing entity data between processing and collection steps +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct ProcessedEntities { + /// List of block entities + pub block_entities: Vec, +} + /// Derives a filename from region coordinates and a file extension /// /// Can be used for input regions, processed data or rendered tiles @@ -122,6 +139,8 @@ pub struct Config { pub output_dir: PathBuf, /// Path for storage of intermediate processed data files pub processed_dir: PathBuf, + /// Path for storage of processed entity data files + pub entities_dir: PathBuf, /// Path of viewer metadata file pub metadata_path: PathBuf, } @@ -137,7 +156,8 @@ impl Config { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); - let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); + let entities_dir = [&processed_dir, Path::new("entities")].iter().collect(); let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); Config { @@ -146,6 +166,7 @@ impl Config { level_dat_path, output_dir: args.output_dir.clone(), processed_dir, + entities_dir, metadata_path, } } @@ -162,6 +183,20 @@ impl Config { [&self.processed_dir, Path::new(&filename)].iter().collect() } + /// Constructs the base output path for processed entity data + pub fn entities_dir(&self, level: usize) -> PathBuf { + [&self.entities_dir, Path::new(&level.to_string())] + .iter() + .collect() + } + + /// Constructs the path of a processed entity data file + pub fn entities_path(&self, level: usize, coords: TileCoords) -> PathBuf { + let filename = coord_filename(coords, "bin"); + let dir = self.entities_dir(level); + [Path::new(&dir), Path::new(&filename)].iter().collect() + } + /// Constructs the base output path for a [TileKind] and mipmap level pub fn tile_dir(&self, kind: TileKind, level: usize) -> PathBuf { let prefix = match kind { diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 52cb165..f1f8441 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -64,20 +64,28 @@ struct SingleRegionProcessor<'a> { output_path: PathBuf, /// Lightmap output filename lightmap_path: PathBuf, + /// Processed entity output filename + entities_path: PathBuf, /// Timestamp of last modification of input file input_timestamp: SystemTime, /// Timestamp of last modification of processed region output file (if valid) output_timestamp: Option, /// Timestamp of last modification of lightmap output file (if valid) lightmap_timestamp: Option, + /// Timestamp of last modification of entity list output file (if valid) + entities_timestamp: Option, /// True if processed region output file needs to be updated output_needed: bool, /// True if lightmap output file needs to be updated lightmap_needed: bool, + /// True if entity output file needs to be updated + entities_needed: bool, /// Processed region intermediate data processed_region: ProcessedRegion, /// Lightmap intermediate data lightmap: image::GrayAlphaImage, + /// Processed entity intermediate data + entities: ProcessedEntities, /// True if any unknown block or biome types were encountered during processing has_unknown: bool, } @@ -93,14 +101,20 @@ impl<'a> SingleRegionProcessor<'a> { let output_path = processor.config.processed_path(coords); let output_timestamp = fs::read_timestamp(&output_path, REGION_FILE_META_VERSION); + let lightmap_path = processor.config.tile_path(TileKind::Lightmap, 0, coords); let lightmap_timestamp = fs::read_timestamp(&lightmap_path, LIGHTMAP_FILE_META_VERSION); + let entities_path = processor.config.entities_path(0, coords); + let entities_timestamp = fs::read_timestamp(&entities_path, ENTITIES_FILE_META_VERSION); + let output_needed = Some(input_timestamp) > output_timestamp; let lightmap_needed = Some(input_timestamp) > lightmap_timestamp; + let entities_needed = Some(input_timestamp) > entities_timestamp; let processed_region = ProcessedRegion::default(); let lightmap = image::GrayAlphaImage::new(N, N); + let entities = ProcessedEntities::default(); Ok(SingleRegionProcessor { block_types: &processor.block_types, @@ -109,13 +123,17 @@ impl<'a> SingleRegionProcessor<'a> { input_path, output_path, lightmap_path, + entities_path, input_timestamp, output_timestamp, lightmap_timestamp, + entities_timestamp, output_needed, lightmap_needed, + entities_needed, processed_region, lightmap, + entities, has_unknown: false, }) } @@ -174,34 +192,57 @@ impl<'a> SingleRegionProcessor<'a> { ) } + /// Saves processed entity data + /// + /// The timestamp is the time of the last modification of the input region data. + fn save_entities(&self) -> Result<()> { + if !self.entities_needed { + return Ok(()); + } + + storage::write_file( + &self.entities_path, + &self.entities, + storage::Format::Json, + ENTITIES_FILE_META_VERSION, + self.input_timestamp, + ) + } + /// Processes a single chunk fn process_chunk(&mut self, chunk_coords: ChunkCoords, data: world::de::Chunk) -> Result<()> { let (chunk, has_unknown) = world::chunk::Chunk::new(&data, self.block_types, self.biome_types) .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; self.has_unknown |= has_unknown; - let Some(layer::LayerData { - blocks, - biomes, - block_light, - depths, - }) = world::layer::top_layer(&mut self.processed_region.biome_list, &chunk) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? - else { - return Ok(()); - }; - if self.output_needed { - self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + if self.output_needed || self.lightmap_needed { + if let Some(layer::LayerData { blocks, biomes, + block_light, depths, - })); + }) = world::layer::top_layer(&mut self.processed_region.biome_list, &chunk) + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + { + if self.output_needed { + self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + blocks, + biomes, + depths, + })); + } + + if self.lightmap_needed { + let chunk_lightmap = Self::render_chunk_lightmap(block_light); + overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + } + } } - if self.lightmap_needed { - let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + if self.entities_needed { + let mut block_entities = chunk.block_entities(); + self.entities.block_entities.append(&mut block_entities); } Ok(()) @@ -215,7 +256,7 @@ impl<'a> SingleRegionProcessor<'a> { /// Processes the region fn run(mut self) -> Result { - if !self.output_needed && !self.lightmap_needed { + if !self.output_needed && !self.lightmap_needed && !self.entities_needed { debug!( "Skipping unchanged region r.{}.{}.mca", self.coords.x, self.coords.z @@ -229,7 +270,10 @@ impl<'a> SingleRegionProcessor<'a> { ); if let Err(err) = self.process_chunks() { - if self.output_timestamp.is_some() && self.lightmap_timestamp.is_some() { + if self.output_timestamp.is_some() + && self.lightmap_timestamp.is_some() + && self.entities_timestamp.is_some() + { warn!( "Failed to process region {:?}, using old data: {:?}", self.coords, err @@ -246,6 +290,7 @@ impl<'a> SingleRegionProcessor<'a> { self.save_region()?; self.save_lightmap()?; + self.save_entities()?; Ok(if self.has_unknown { RegionProcessorStatus::OkWithUnknown @@ -313,6 +358,7 @@ impl<'a> RegionProcessor<'a> { pub fn run(self) -> Result> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; + fs::create_dir_all(&self.config.entities_dir(0))?; info!("Processing region files..."); From 825cf70e515d84cb20cfb42c4f7afdfc88df2312 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 01:20:09 +0100 Subject: [PATCH 017/152] core: split TileCollector trait out of TileMipmapper Make mipmap-style recursive processing of tiles reusable. --- src/core/mod.rs | 1 + src/core/tile_collector.rs | 107 +++++++++++++++++++ src/core/tile_mipmapper.rs | 205 ++++++++++++++++++------------------- 3 files changed, 206 insertions(+), 107 deletions(-) create mode 100644 src/core/tile_collector.rs diff --git a/src/core/mod.rs b/src/core/mod.rs index 0e77768..e3f2ea3 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -4,6 +4,7 @@ mod common; mod metadata_writer; mod region_group; mod region_processor; +mod tile_collector; mod tile_mipmapper; mod tile_renderer; diff --git a/src/core/tile_collector.rs b/src/core/tile_collector.rs new file mode 100644 index 0000000..dfc6085 --- /dev/null +++ b/src/core/tile_collector.rs @@ -0,0 +1,107 @@ +//! A trait for recursively processing tiles +//! +//! Used for mipmap generation and collecting entity data + +use std::sync::mpsc; + +use anyhow::Result; +use rayon::prelude::*; + +use super::common::*; + +/// Helper to determine if no further mipmap levels are needed +/// +/// If all tile coordinates are -1 or 0, further mipmap levels will not +/// decrease the number of tiles and mipmap generated is considered finished. +fn done(tiles: &TileCoordMap) -> bool { + tiles + .0 + .iter() + .all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x))) +} + +/// Derives the map of populated tile coordinates for the next mipmap level +fn map_coords(tiles: &TileCoordMap) -> TileCoordMap { + let mut ret = TileCoordMap::default(); + + for (&z, xs) in &tiles.0 { + for &x in xs { + let xt = x >> 1; + let zt = z >> 1; + + ret.0.entry(zt).or_default().insert(xt); + } + } + + ret +} + +/// Trait to implement for collecting tiles recursively +pub trait TileCollector: Sync { + /// Return value of [TileCollector::collect_one] + type CollectOutput: Send; + + /// List of level 0 tiles + fn tiles(&self) -> &[TileCoords]; + + /// Called at the beginning of each level of processing + fn prepare(&self, level: usize) -> Result<()>; + + /// Called at the end of each level of processing + fn finish( + &self, + level: usize, + outputs: impl Iterator, + ) -> Result<()>; + + /// Called for each tile coordinate of the level that is currently being generated + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result; + + /// Collects tiles recursively + fn collect_tiles(&self) -> Result> { + let mut tile_stack = { + let mut tile_map = TileCoordMap::default(); + + for &TileCoords { x, z } in self.tiles() { + tile_map.0.entry(z).or_default().insert(x); + } + + vec![tile_map] + }; + + loop { + let level = tile_stack.len(); + let prev = &tile_stack[level - 1]; + if done(prev) { + break; + } + + self.prepare(level)?; + + let next = map_coords(prev); + + let (send, recv) = mpsc::channel(); + + next.0 + .par_iter() + .flat_map(|(&z, xs)| xs.par_iter().map(move |&x| TileCoords { x, z })) + .try_for_each(|coords| { + let output = self.collect_one(level, coords, prev)?; + send.send(output).unwrap(); + anyhow::Ok(()) + })?; + + drop(send); + self.finish(level, recv.into_iter())?; + + tile_stack.push(next); + } + + Ok(tile_stack) + } +} diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index 6ea8750..a372ca5 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -1,14 +1,53 @@ //! The [TileMipmapper] -use std::sync::mpsc; +use std::ops::Add; use anyhow::{Context, Result}; -use rayon::prelude::*; use tracing::{debug, info, warn}; -use super::common::*; +use super::{common::*, tile_collector::TileCollector}; use crate::{io::fs, types::*}; +/// Counters for the number of processed and total tiles +/// +/// Used as return of [TileMipmapper::collect_one] +#[derive(Debug, Clone, Copy)] +pub struct MipmapStat { + /// Total number of tiles + total: usize, + /// Processed number of tiles + processed: usize, +} + +impl MipmapStat { + /// Mipmap step return when none of the input files exist + const NOT_FOUND: MipmapStat = MipmapStat { + total: 0, + processed: 0, + }; + /// Mipmap step return when output file is up-to-date + const SKIPPED: MipmapStat = MipmapStat { + total: 1, + processed: 0, + }; + /// Mipmap step return when a new output file has been generated + const PROCESSED: MipmapStat = MipmapStat { + total: 1, + processed: 1, + }; +} + +impl Add for MipmapStat { + type Output = MipmapStat; + + fn add(self, rhs: Self) -> Self::Output { + MipmapStat { + total: self.total + rhs.total, + processed: self.processed + rhs.processed, + } + } +} + /// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'a> { /// Common MinedMap configuration from command line @@ -17,39 +56,63 @@ pub struct TileMipmapper<'a> { regions: &'a [TileCoords], } +impl<'a> TileCollector for TileMipmapper<'a> { + type CollectOutput = MipmapStat; + + fn tiles(&self) -> &[TileCoords] { + self.regions + } + + fn prepare(&self, level: usize) -> Result<()> { + info!("Generating level {} mipmaps...", level); + + fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?; + fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?; + + Ok(()) + } + + fn finish( + &self, + level: usize, + outputs: impl Iterator, + ) -> Result<()> { + let stat = outputs.fold( + MipmapStat { + total: 0, + processed: 0, + }, + MipmapStat::add, + ); + info!( + "Generated level {} mipmaps ({} processed, {} unchanged)", + level, + stat.processed, + stat.total - stat.processed, + ); + + Ok(()) + } + + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result { + let map_stat = self.render_mipmap::>(TileKind::Map, level, coords, prev)?; + let lightmap_stat = + self.render_mipmap::>(TileKind::Lightmap, level, coords, prev)?; + Ok(map_stat + lightmap_stat) + } +} + impl<'a> TileMipmapper<'a> { /// Constructs a new TileMipmapper pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self { TileMipmapper { config, regions } } - /// Helper to determine if no further mipmap levels are needed - /// - /// If all tile coordinates are -1 or 0, further mipmap levels will not - /// decrease the number of tiles and mipmap generated is considered finished. - fn done(tiles: &TileCoordMap) -> bool { - tiles - .0 - .iter() - .all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x))) - } - - /// Derives the map of populated tile coordinates for the next mipmap level - fn map_coords(tiles: &TileCoordMap) -> TileCoordMap { - let mut ret = TileCoordMap::default(); - - for (&z, xs) in &tiles.0 { - for &x in xs { - let xt = x >> 1; - let zt = z >> 1; - - ret.0.entry(zt).or_default().insert(xt); - } - } - - ret - } - /// Renders and saves a single mipmap tile image /// /// Each mipmap tile is rendered by taking 2x2 tiles from the @@ -60,9 +123,7 @@ impl<'a> TileMipmapper<'a> { level: usize, coords: TileCoords, prev: &TileCoordMap, - count_total: &mpsc::Sender<()>, - count_processed: &mpsc::Sender<()>, - ) -> Result<()> + ) -> Result where [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, @@ -97,11 +158,9 @@ impl<'a> TileMipmapper<'a> { .collect(); let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { - return Ok(()); + return Ok(MipmapStat::NOT_FOUND); }; - count_total.send(()).unwrap(); - if Some(input_timestamp) <= output_timestamp { debug!( "Skipping unchanged mipmap tile {}", @@ -110,7 +169,7 @@ impl<'a> TileMipmapper<'a> { .expect("tile path must be in output directory") .display(), ); - return Ok(()); + return Ok(MipmapStat::SKIPPED); } debug!( @@ -156,79 +215,11 @@ impl<'a> TileMipmapper<'a> { }, )?; - count_processed.send(()).unwrap(); - Ok(()) + Ok(MipmapStat::PROCESSED) } /// Runs the mipmap generation pub fn run(self) -> Result> { - let mut tile_stack = { - let mut tile_map = TileCoordMap::default(); - - for &TileCoords { x, z } in self.regions { - tile_map.0.entry(z).or_default().insert(x); - } - - vec![tile_map] - }; - - loop { - let level = tile_stack.len(); - let prev = &tile_stack[level - 1]; - if Self::done(prev) { - break; - } - - info!("Generating level {} mipmaps...", level); - - fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?; - fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?; - - let next = Self::map_coords(prev); - - let (total_send, total_recv) = mpsc::channel(); - let (processed_send, processed_recv) = mpsc::channel(); - - next.0 - .par_iter() - .flat_map(|(&z, xs)| xs.par_iter().map(move |&x| TileCoords { x, z })) - .try_for_each(|coords| { - self.render_mipmap::>( - TileKind::Map, - level, - coords, - prev, - &total_send, - &processed_send, - )?; - self.render_mipmap::>( - TileKind::Lightmap, - level, - coords, - prev, - &total_send, - &processed_send, - )?; - - anyhow::Ok(()) - })?; - - drop(total_send); - let total = total_recv.into_iter().count(); - - drop(processed_send); - let processed = processed_recv.into_iter().count(); - - info!( - "Generated level {} mipmaps ({} processed, {} unchanged)", - level, - processed, - total - processed, - ); - - tile_stack.push(next); - } - - Ok(tile_stack) + self.collect_tiles() } } From e36ae4601df41bbe0df4b801832a06d99ca9d639 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 12:27:18 +0100 Subject: [PATCH 018/152] world: add Eq + Ord to all block entity types --- src/world/block_entity.rs | 8 ++++---- src/world/json_text.rs | 4 ++-- src/world/sign.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs index 65d95e4..9e60a23 100644 --- a/src/world/block_entity.rs +++ b/src/world/block_entity.rs @@ -8,7 +8,7 @@ use super::{ }; /// Kind of sign block -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum SignKind { /// Standing or attached sign @@ -18,7 +18,7 @@ pub enum SignKind { } /// Processed sign data -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct Sign { /// The kind of the sign pub kind: SignKind, @@ -45,7 +45,7 @@ impl Sign { } /// Data for different kinds of [BlockEntity] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(tag = "type", rename_all = "snake_case")] pub enum BlockEntityData { /// A sign block @@ -53,7 +53,7 @@ pub enum BlockEntityData { } /// A processed block entity -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct BlockEntity { /// Global X coordinate pub x: i32, diff --git a/src/world/json_text.rs b/src/world/json_text.rs index a9c1f13..0f72dcc 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; /// is handled by [DeserializedText]. /// /// Formatting that is not set in a node is inherited from the parent. -#[derive(Debug, Serialize, Deserialize, Default)] +#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)] pub struct FormattedText { #[serde(default)] /// Text content @@ -77,7 +77,7 @@ impl From for FormattedTextTree { } /// List of [FormattedText] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub struct FormattedTextList(pub Vec); impl FormattedTextList { diff --git a/src/world/sign.rs b/src/world/sign.rs index e53be87..43cac47 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -79,7 +79,7 @@ impl BlockEntitySignExt for de::BlockEntitySign { } } -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] /// Deserialized and linearized sign text pub struct SignText(pub Vec); From 7740ce0522d3459b7f905346c3b864b2aa75802d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 12:27:43 +0100 Subject: [PATCH 019/152] core/region_processor: sort processed block entities Make the block entity list more reproducible when the stored chunk order changes. --- src/core/region_processor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index f1f8441..cff87b7 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -195,11 +195,13 @@ impl<'a> SingleRegionProcessor<'a> { /// Saves processed entity data /// /// The timestamp is the time of the last modification of the input region data. - fn save_entities(&self) -> Result<()> { + fn save_entities(&mut self) -> Result<()> { if !self.entities_needed { return Ok(()); } + self.entities.block_entities.sort_unstable(); + storage::write_file( &self.entities_path, &self.entities, From 0f308788ef7b1579407b5a7f18b153179cf9bb7e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 02:28:11 +0100 Subject: [PATCH 020/152] core: split TileMerger out of TileMipmapper Reusable mipmap-style tile merging --- src/core/mod.rs | 1 + src/core/tile_merger.rs | 97 ++++++++++++++++ src/core/tile_mipmapper.rs | 228 ++++++++++++++++++++----------------- 3 files changed, 220 insertions(+), 106 deletions(-) create mode 100644 src/core/tile_merger.rs diff --git a/src/core/mod.rs b/src/core/mod.rs index e3f2ea3..f892a62 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -5,6 +5,7 @@ mod metadata_writer; mod region_group; mod region_processor; mod tile_collector; +mod tile_merger; mod tile_mipmapper; mod tile_renderer; diff --git a/src/core/tile_merger.rs b/src/core/tile_merger.rs new file mode 100644 index 0000000..3a14390 --- /dev/null +++ b/src/core/tile_merger.rs @@ -0,0 +1,97 @@ +//! Mipmap-style merging of tiles + +use std::{ + fs::File, + io::BufWriter, + path::{Path, PathBuf}, + time::SystemTime, +}; + +use anyhow::Result; +use tracing::warn; + +use super::common::*; +use crate::io::fs; + +/// [TileMerger::merge_tiles] return +#[derive(Debug, Clone, Copy)] +pub enum Stat { + /// None of the input files were found + NotFound, + /// The output file is up-to-date + Skipped, + /// The output file is regenerated + Regenerate, +} + +/// A source file for the [TileMerger] +/// +/// The tuple elements are X and Z coordinate offsets in the range [0, 1], +/// the file path and the time of last change of the input. +pub type Source = ((i32, i32), PathBuf, SystemTime); + +/// Reusable trait for mipmap-style tile merging with change tracking +pub trait TileMerger { + /// [fs::FileMetaVersion] of input and output files + /// + /// The version in the file metadata on disk must match the returned + /// version for the a to be considered up-to-date. + fn file_meta_version(&self) -> fs::FileMetaVersion; + + /// Returns the paths of input and output files + fn tile_path(&self, level: usize, coords: TileCoords) -> PathBuf; + + /// Can be used to log the processing status + fn log(&self, _output_path: &Path, _stat: Stat) {} + + /// Handles the actual merging of source files + fn write_tile(&self, file: &mut BufWriter, sources: &[Source]) -> Result<()>; + + /// Generates a tile at given coordinates and mipmap level + fn merge_tiles(&self, level: usize, coords: TileCoords, prev: &TileCoordMap) -> Result { + let version = self.file_meta_version(); + let output_path = self.tile_path(level, coords); + let output_timestamp = fs::read_timestamp(&output_path, version); + + let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] + .into_iter() + .filter_map(|(dx, dz)| { + let source_coords = TileCoords { + x: 2 * coords.x + dx, + z: 2 * coords.z + dz, + }; + if !prev.contains(source_coords) { + return None; + } + + let source_path = self.tile_path(level - 1, source_coords); + let timestamp = match fs::modified_timestamp(&source_path) { + Ok(timestamp) => timestamp, + Err(err) => { + warn!("{}", err); + return None; + } + }; + Some(((dx, dz), source_path, timestamp)) + }) + .collect(); + + let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { + self.log(&output_path, Stat::NotFound); + return Ok(Stat::NotFound); + }; + + if Some(input_timestamp) <= output_timestamp { + self.log(&output_path, Stat::Skipped); + return Ok(Stat::Skipped); + } + + self.log(&output_path, Stat::Regenerate); + + fs::create_with_timestamp(&output_path, version, input_timestamp, |file| { + self.write_tile(file, &sources) + })?; + + Ok(Stat::Regenerate) + } +} diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index a372ca5..1873cf9 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -1,11 +1,15 @@ //! The [TileMipmapper] -use std::ops::Add; +use std::{marker::PhantomData, ops::Add}; use anyhow::{Context, Result}; use tracing::{debug, info, warn}; -use super::{common::*, tile_collector::TileCollector}; +use super::{ + common::*, + tile_collector::TileCollector, + tile_merger::{self, TileMerger}, +}; use crate::{io::fs, types::*}; /// Counters for the number of processed and total tiles @@ -19,22 +23,23 @@ pub struct MipmapStat { processed: usize, } -impl MipmapStat { - /// Mipmap step return when none of the input files exist - const NOT_FOUND: MipmapStat = MipmapStat { - total: 0, - processed: 0, - }; - /// Mipmap step return when output file is up-to-date - const SKIPPED: MipmapStat = MipmapStat { - total: 1, - processed: 0, - }; - /// Mipmap step return when a new output file has been generated - const PROCESSED: MipmapStat = MipmapStat { - total: 1, - processed: 1, - }; +impl From for MipmapStat { + fn from(value: tile_merger::Stat) -> Self { + match value { + tile_merger::Stat::NotFound => MipmapStat { + total: 0, + processed: 0, + }, + tile_merger::Stat::Skipped => MipmapStat { + total: 1, + processed: 0, + }, + tile_merger::Stat::Regenerate => MipmapStat { + total: 1, + processed: 1, + }, + } + } } impl Add for MipmapStat { @@ -48,6 +53,102 @@ impl Add for MipmapStat { } } +/// [TileMerger] for map tile images +struct MapMerger<'a, P> { + /// Common MinedMap configuration from command line + config: &'a Config, + /// Tile kind (map or lightmap) + kind: TileKind, + /// Pixel format type + _pixel: PhantomData

, +} + +impl<'a, P> MapMerger<'a, P> { + /// Creates a new [MapMerger] + fn new(config: &'a Config, kind: TileKind) -> Self { + MapMerger { + config, + kind, + _pixel: PhantomData, + } + } +} + +impl<'a, P: image::PixelWithColorType> TileMerger for MapMerger<'a, P> +where + [P::Subpixel]: image::EncodableLayout, + image::ImageBuffer>: Into, +{ + fn file_meta_version(&self) -> fs::FileMetaVersion { + MIPMAP_FILE_META_VERSION + } + + fn tile_path(&self, level: usize, coords: TileCoords) -> std::path::PathBuf { + self.config.tile_path(self.kind, level, coords) + } + + fn log(&self, output_path: &std::path::Path, stat: super::tile_merger::Stat) { + match stat { + super::tile_merger::Stat::NotFound => {} + super::tile_merger::Stat::Skipped => { + debug!( + "Skipping unchanged mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + } + super::tile_merger::Stat::Regenerate => { + debug!( + "Rendering mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + } + }; + } + + fn write_tile( + &self, + file: &mut std::io::BufWriter, + sources: &[super::tile_merger::Source], + ) -> Result<()> { + /// Tile width/height + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let mut image: image::DynamicImage = + image::ImageBuffer::>::new(N, N).into(); + + for ((dx, dz), source_path, _) in sources { + let source = match image::open(source_path) { + Ok(source) => source, + Err(err) => { + warn!( + "Failed to read source image {}: {}", + source_path.display(), + err, + ); + continue; + } + }; + let resized = source.resize(N / 2, N / 2, image::imageops::FilterType::Triangle); + image::imageops::overlay( + &mut image, + &resized, + *dx as i64 * (N / 2) as i64, + *dz as i64 * (N / 2) as i64, + ); + } + + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + } +} + /// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'a> { /// Common MinedMap configuration from command line @@ -128,94 +229,9 @@ impl<'a> TileMipmapper<'a> { [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, { - /// Tile width/height - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - - let output_path = self.config.tile_path(kind, level, coords); - let output_timestamp = fs::read_timestamp(&output_path, MIPMAP_FILE_META_VERSION); - - let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] - .into_iter() - .filter_map(|(dx, dz)| { - let source_coords = TileCoords { - x: 2 * coords.x + dx, - z: 2 * coords.z + dz, - }; - if !prev.contains(source_coords) { - return None; - } - - let source_path = self.config.tile_path(kind, level - 1, source_coords); - let timestamp = match fs::modified_timestamp(&source_path) { - Ok(timestamp) => timestamp, - Err(err) => { - warn!("{}", err); - return None; - } - }; - Some(((dx, dz), source_path, timestamp)) - }) - .collect(); - - let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { - return Ok(MipmapStat::NOT_FOUND); - }; - - if Some(input_timestamp) <= output_timestamp { - debug!( - "Skipping unchanged mipmap tile {}", - output_path - .strip_prefix(&self.config.output_dir) - .expect("tile path must be in output directory") - .display(), - ); - return Ok(MipmapStat::SKIPPED); - } - - debug!( - "Rendering mipmap tile {}", - output_path - .strip_prefix(&self.config.output_dir) - .expect("tile path must be in output directory") - .display(), - ); - - let mut image: image::DynamicImage = - image::ImageBuffer::>::new(N, N).into(); - - for ((dx, dz), source_path, _) in sources { - let source = match image::open(&source_path) { - Ok(source) => source, - Err(err) => { - warn!( - "Failed to read source image {}: {}", - source_path.display(), - err, - ); - continue; - } - }; - let resized = source.resize(N / 2, N / 2, image::imageops::FilterType::Triangle); - image::imageops::overlay( - &mut image, - &resized, - dx as i64 * (N / 2) as i64, - dz as i64 * (N / 2) as i64, - ); - } - - fs::create_with_timestamp( - &output_path, - MIPMAP_FILE_META_VERSION, - input_timestamp, - |file| { - image - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }, - )?; - - Ok(MipmapStat::PROCESSED) + let merger = MapMerger::

::new(self.config, kind); + let ret = merger.merge_tiles(level, coords, prev)?; + Ok(ret.into()) } /// Runs the mipmap generation From 1143396068b1e0c7310ad49968709508a0934281 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 13:50:05 +0100 Subject: [PATCH 021/152] core: use debug format for logging errors Show the full cause stack. --- src/core/tile_merger.rs | 2 +- src/core/tile_mipmapper.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/tile_merger.rs b/src/core/tile_merger.rs index 3a14390..6f3cc22 100644 --- a/src/core/tile_merger.rs +++ b/src/core/tile_merger.rs @@ -68,7 +68,7 @@ pub trait TileMerger { let timestamp = match fs::modified_timestamp(&source_path) { Ok(timestamp) => timestamp, Err(err) => { - warn!("{}", err); + warn!("{:?}", err); return None; } }; diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index 1873cf9..cd90e20 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -127,7 +127,7 @@ where Ok(source) => source, Err(err) => { warn!( - "Failed to read source image {}: {}", + "Failed to read source image {}: {:?}", source_path.display(), err, ); From cde6a4b6e602bfabecdcd00caf9d63e83b0b45dc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 12:39:51 +0100 Subject: [PATCH 022/152] core: merge entity data for all regions into one file Introduce the EntityCollector, using the TileCollector and TileMerger traits. --- src/core/common.rs | 6 +- src/core/entity_collector.rs | 123 +++++++++++++++++++++++++++++++++++ src/core/mod.rs | 4 ++ 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/core/entity_collector.rs diff --git a/src/core/common.rs b/src/core/common.rs index cd8fd8f..7280be9 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -141,6 +141,8 @@ pub struct Config { pub processed_dir: PathBuf, /// Path for storage of processed entity data files pub entities_dir: PathBuf, + /// Path for storage of the final merged processed entity data file + pub entities_path_final: PathBuf, /// Path of viewer metadata file pub metadata_path: PathBuf, } @@ -157,7 +159,8 @@ impl Config { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); - let entities_dir = [&processed_dir, Path::new("entities")].iter().collect(); + let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect(); + let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect(); let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); Config { @@ -167,6 +170,7 @@ impl Config { output_dir: args.output_dir.clone(), processed_dir, entities_dir, + entities_path_final, metadata_path, } } diff --git a/src/core/entity_collector.rs b/src/core/entity_collector.rs new file mode 100644 index 0000000..3d9b6ab --- /dev/null +++ b/src/core/entity_collector.rs @@ -0,0 +1,123 @@ +//! The [EntityCollector] + +use std::path::Path; + +use anyhow::{Context, Result}; +use tracing::{info, warn}; + +use super::{common::*, tile_collector::TileCollector, tile_merger::TileMerger}; +use crate::io::{fs, storage}; + +/// Generates mipmap tiles from full-resolution tile images +pub struct EntityCollector<'a> { + /// Common MinedMap configuration from command line + config: &'a Config, + /// List of populated tiles for base mipmap level (level 0) + regions: &'a [TileCoords], +} + +impl<'a> TileMerger for EntityCollector<'a> { + fn file_meta_version(&self) -> fs::FileMetaVersion { + ENTITIES_FILE_META_VERSION + } + + fn tile_path(&self, level: usize, coords: TileCoords) -> std::path::PathBuf { + self.config.entities_path(level, coords) + } + + fn write_tile( + &self, + file: &mut std::io::BufWriter, + sources: &[super::tile_merger::Source], + ) -> Result<()> { + Self::merge_entity_lists(file, sources.iter().map(|source| &source.1)) + } +} + +impl<'a> TileCollector for EntityCollector<'a> { + type CollectOutput = (); + + fn tiles(&self) -> &[TileCoords] { + self.regions + } + + fn prepare(&self, level: usize) -> Result<()> { + fs::create_dir_all(&self.config.entities_dir(level)) + } + + fn finish( + &self, + _level: usize, + _outputs: impl Iterator, + ) -> Result<()> { + Ok(()) + } + + fn collect_one( + &self, + level: usize, + coords: TileCoords, + prev: &TileCoordMap, + ) -> Result { + self.merge_tiles(level, coords, prev)?; + Ok(()) + } +} + +impl<'a> EntityCollector<'a> { + /// Constructs a new EntityCollector + pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self { + EntityCollector { config, regions } + } + + /// Merges multiple entity lists into one + fn merge_entity_lists>( + file: &mut std::io::BufWriter, + sources: impl Iterator, + ) -> Result<()> { + let mut output = ProcessedEntities::default(); + + for source_path in sources { + let mut source: ProcessedEntities = + match storage::read_file(source_path.as_ref(), storage::Format::Json) { + Ok(source) => source, + Err(err) => { + warn!( + "Failed to read entity data file {}: {:?}", + source_path.as_ref().display(), + err, + ); + continue; + } + }; + + output.block_entities.append(&mut source.block_entities); + } + + storage::write(file, &output, storage::Format::Json).context("Failed to write entity data") + } + + /// Runs the mipmap generation + pub fn run(self) -> Result<()> { + info!("Collecting entity data..."); + + let tile_stack = self.collect_tiles()?; + + // Final merge + let level = tile_stack.len() - 1; + let tile_map = &tile_stack[level]; + let sources: Vec<_> = [(-1, -1), (-1, 0), (0, -1), (0, 0)] + .into_iter() + .map(|(x, z)| TileCoords { x, z }) + .filter(|&coords| tile_map.contains(coords)) + .map(|coords| self.tile_path(level, coords)) + .collect(); + + fs::create_with_tmpfile(&self.config.entities_path_final, |file| { + Self::merge_entity_lists(file, sources.iter()) + })?; + + info!("Collected entity data."); + Ok(()) + } +} diff --git a/src/core/mod.rs b/src/core/mod.rs index f892a62..61bdb76 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,6 +1,7 @@ //! Core functions of the MinedMap CLI mod common; +mod entity_collector; mod metadata_writer; mod region_group; mod region_processor; @@ -21,6 +22,8 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; +use self::entity_collector::EntityCollector; + /// MinedMap version number const VERSION: &str = git_version!( args = ["--abbrev=7", "--match=v*", "--dirty=-modified"], @@ -77,6 +80,7 @@ pub fn cli() -> Result<()> { let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config, &rt, ®ions).run()?; let tiles = TileMipmapper::new(&config, ®ions).run()?; + EntityCollector::new(&config, ®ions).run()?; MetadataWriter::new(&config, &tiles).run()?; Ok(()) From d29c0df25db287a3f9cbd2b4bfad7712428e9c91 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 15:31:57 +0100 Subject: [PATCH 023/152] core/metadata_writer: write entity list for viewer --- src/core/common.rs | 12 +++++++++--- src/core/metadata_writer.rs | 39 +++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 7280be9..d961ea9 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -144,7 +144,9 @@ pub struct Config { /// Path for storage of the final merged processed entity data file pub entities_path_final: PathBuf, /// Path of viewer metadata file - pub metadata_path: PathBuf, + pub viewer_info_path: PathBuf, + /// Path of viewer entities file + pub viewer_entities_path: PathBuf, } impl Config { @@ -161,7 +163,10 @@ impl Config { let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect(); let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect(); - let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); + let viewer_info_path = [&args.output_dir, Path::new("info.json")].iter().collect(); + let viewer_entities_path = [&args.output_dir, Path::new("entities.json")] + .iter() + .collect(); Config { num_threads, @@ -171,7 +176,8 @@ impl Config { processed_dir, entities_dir, entities_path_final, - metadata_path, + viewer_info_path, + viewer_entities_path, } } diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index 5783356..caf7726 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -3,7 +3,11 @@ use anyhow::{Context, Result}; use serde::Serialize; -use crate::{core::common::*, io::fs, world::de}; +use crate::{ + core::common::*, + io::{fs, storage}, + world::{block_entity::BlockEntity, de}, +}; /// Minimum and maximum X and Z tile coordinates for a mipmap level #[derive(Debug, Serialize)] @@ -46,6 +50,13 @@ struct Metadata<'t> { spawn: Spawn, } +/// Viewer entity JSON data structure +#[derive(Debug, Serialize, Default)] +struct Entities { + /// List of signs + signs: Vec, +} + /// The MetadataWriter is used to generate the viewer metadata file pub struct MetadataWriter<'a> { /// Common MinedMap configuration from command line @@ -109,6 +120,19 @@ impl<'a> MetadataWriter<'a> { } } + /// Generates [Entities] data from collected entity lists + fn entities(&self) -> Result { + let data: ProcessedEntities = + storage::read_file(&self.config.entities_path_final, storage::Format::Json) + .context("Failed to read entity data file")?; + + let ret = Entities { + signs: data.block_entities, + }; + + Ok(ret) + } + /// Runs the viewer metadata file generation pub fn run(self) -> Result<()> { let level_dat = self.read_level_dat()?; @@ -122,8 +146,15 @@ impl<'a> MetadataWriter<'a> { metadata.mipmaps.push(Self::mipmap_entry(tile_map)); } - fs::create_with_tmpfile(&self.config.metadata_path, |file| { - serde_json::to_writer(file, &metadata).context("Failed to write metadata") - }) + fs::create_with_tmpfile(&self.config.viewer_info_path, |file| { + serde_json::to_writer(file, &metadata).context("Failed to write info.json") + })?; + + let entities = self.entities()?; + fs::create_with_tmpfile(&self.config.viewer_entities_path, |file| { + serde_json::to_writer(file, &entities).context("Failed to write entities.json") + })?; + + Ok(()) } } From 1874d3082dc35830e9091860391f7043bac21fea Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Dec 2023 21:09:34 +0100 Subject: [PATCH 024/152] resource: fix typo in doc comment --- crates/resource/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index a832a58..ad3553f 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -27,7 +27,7 @@ pub enum BlockFlag { Foliage, /// The block type is birch foliage Birch, - /// The block type is spurce foliage + /// The block type is spruce foliage Spruce, /// The block type is colored using biome water colors Water, From 8814dcff89431cfe4b9935105ee8d0bdf1e194bf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Dec 2023 01:42:17 +0100 Subject: [PATCH 025/152] resource: split BlockType in Copy and !Copy parts Preparation for actually adding !Copy fields to BlockType. Only the Copy parts are added to the processed data, avoiding .clone() for the most part. --- crates/resource/src/block_color.rs | 10 +- crates/resource/src/block_types.rs | 6048 ++++++++++++++++++---------- crates/resource/src/lib.rs | 30 +- resource/generate.py | 6 +- src/world/layer.rs | 14 +- src/world/section.rs | 8 +- 6 files changed, 4073 insertions(+), 2043 deletions(-) diff --git a/crates/resource/src/block_color.rs b/crates/resource/src/block_color.rs index cffebeb..e95e0ed 100644 --- a/crates/resource/src/block_color.rs +++ b/crates/resource/src/block_color.rs @@ -1,6 +1,6 @@ //! Functions for computations of block colors -use super::{Biome, BlockType, Color, Colorf}; +use super::{Biome, BlockColor, Color, Colorf}; /// Converts an u8 RGB color to a float vector fn color_vec_unscaled(color: Color) -> Colorf { @@ -91,18 +91,18 @@ const BIRCH_COLOR: Colorf = Colorf::new(0.502, 0.655, 0.333); // == color_vec(Co /// Color multiplier for spruce leaves const EVERGREEN_COLOR: Colorf = Colorf::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) -/// Determined if calling [block_color] for a given [BlockType] needs biome information -pub fn needs_biome(block: BlockType) -> bool { +/// Determined if calling [block_color] for a given [BlockColor] needs biome information +pub fn needs_biome(block: BlockColor) -> bool { use super::BlockFlag::*; block.is(Grass) || block.is(Foliage) || block.is(Water) } -/// Determined the block color to display for a given [BlockType] +/// Determined the block color to display for a given [BlockColor] /// /// [needs_biome] must be used to determine whether passing a [Biome] is necessary. /// Will panic if a [Biome] is necessary, but none is passed. -pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> Colorf { +pub fn block_color(block: BlockColor, biome: Option<&Biome>, depth: f32) -> Colorf { use super::BlockFlag::*; let get_biome = || biome.expect("needs biome to determine block color"); diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index a70106c..87d57c8 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -6,5692 +6,7318 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ ( "acacia_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "acacia_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([167, 95, 60]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([167, 95, 60]), + }, }, ), ( "acacia_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "acacia_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([149, 148, 148]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([149, 148, 148]), + }, }, ), ( "acacia_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 88, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 88, 55]), + }, }, ), ( "acacia_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 23]), + }, }, ), ( "acacia_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 90, 50]), + }, }, ), ( "acacia_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([156, 87, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([156, 87, 51]), + }, }, ), ( "acacia_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "acacia_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "acacia_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 96, 86]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 96, 86]), + }, }, ), ( "activator_rail", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 87, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 87, 74]), + }, }, ), ( "air", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "allium", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "amethyst_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([133, 97, 191]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([133, 97, 191]), + }, }, ), ( "amethyst_cluster", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 126, 207]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 126, 207]), + }, }, ), ( "ancient_debris", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 66, 58]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 66, 58]), + }, }, ), ( "andesite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, }, ), ( "andesite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, }, ), ( "andesite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, }, ), ( "andesite_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 136, 136]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 136, 136]), + }, }, ), ( "anvil", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, }, ), ( "attached_melon_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([141, 142, 141]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([141, 142, 141]), + }, }, ), ( "attached_pumpkin_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([139, 139, 139]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([139, 139, 139]), + }, }, ), ( "azalea", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 124, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 124, 47]), + }, }, ), ( "azalea_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 114, 44]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 114, 44]), + }, }, ), ( "azure_bluet", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bamboo", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 144, 19]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 144, 19]), + }, }, ), ( "bamboo_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([139, 141, 62]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([139, 141, 62]), + }, }, ), ( "bamboo_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bamboo_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 171, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 171, 81]), + }, }, ), ( "bamboo_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bamboo_mosaic", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, }, ), ( "bamboo_mosaic_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, }, ), ( "bamboo_mosaic_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 170, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, }, ), ( "bamboo_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bamboo_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, }, ), ( "bamboo_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 179, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 179, 85]), + }, }, ), ( "bamboo_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bamboo_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "barrel", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 100, 58]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 100, 58]), + }, }, ), ( "barrier", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "basalt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 81, 86]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 81, 86]), + }, }, ), ( "beacon", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 220, 215]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 220, 215]), + }, }, ), ( "bedrock", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 85, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 85, 85]), + }, }, ), ( "bee_nest", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([202, 160, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([202, 160, 74]), + }, }, ), ( "beehive", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([180, 146, 90]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([180, 146, 90]), + }, }, ), ( "beetroots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 91, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 91, 30]), + }, }, ), ( "bell", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([253, 235, 110]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([253, 235, 110]), + }, }, ), ( "big_dripleaf", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 141, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 141, 51]), + }, }, ), ( "big_dripleaf_stem", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "birch_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "birch_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 209, 176]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 209, 176]), + }, }, ), ( "birch_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "birch_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Birch}), - color: Color([130, 129, 130]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Birch}), + color: Color([130, 129, 130]), + }, }, ), ( "birch_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 179, 135]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 179, 135]), + }, }, ), ( "birch_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 160, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 160, 79]), + }, }, ), ( "birch_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 175, 121]), + }, }, ), ( "birch_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 194, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 194, 157]), + }, }, ), ( "birch_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "birch_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "birch_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 215, 210]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 215, 210]), + }, }, ), ( "black_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "black_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "black_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "black_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "black_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 21, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 21, 25]), + }, }, ), ( "black_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([8, 10, 15]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([8, 10, 15]), + }, }, ), ( "black_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 26, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 26, 31]), + }, }, ), ( "black_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([67, 30, 32]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([67, 30, 32]), + }, }, ), ( "black_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 25, 29]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 25, 29]), + }, }, ), ( "black_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([25, 25, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([25, 25, 25]), + }, }, ), ( "black_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([24, 24, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([24, 24, 24]), + }, }, ), ( "black_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([37, 22, 16]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([37, 22, 16]), + }, }, ), ( "black_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "black_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 21, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 21, 25]), + }, }, ), ( "blackstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, }, ), ( "blackstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, }, ), ( "blackstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, }, ), ( "blackstone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 36, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 36, 41]), + }, }, ), ( "blast_furnace", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 81]), + }, }, ), ( "blue_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "blue_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "blue_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "blue_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "blue_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 57, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 57, 157]), + }, }, ), ( "blue_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 46, 143]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 46, 143]), + }, }, ), ( "blue_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 73, 166]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 73, 166]), + }, }, ), ( "blue_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 64, 139]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 64, 139]), + }, }, ), ( "blue_ice", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([116, 167, 253]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([116, 167, 253]), + }, }, ), ( "blue_orchid", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "blue_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 45, 140]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 45, 140]), + }, }, ), ( "blue_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 76, 178]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 76, 178]), + }, }, ), ( "blue_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 73, 171]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 73, 171]), + }, }, ), ( "blue_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 59, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 59, 91]), + }, }, ), ( "blue_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "blue_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 57, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 57, 157]), + }, }, ), ( "bone_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([209, 206, 179]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([209, 206, 179]), + }, }, ), ( "bookshelf", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "brain_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brain_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 91, 159]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 91, 159]), + }, }, ), ( "brain_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brain_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brewing_stand", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 100, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 100, 80]), + }, }, ), ( "brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, }, ), ( "brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, }, ), ( "brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, }, ), ( "bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([150, 97, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([150, 97, 83]), + }, }, ), ( "brown_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brown_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brown_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brown_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "brown_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 71, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 71, 40]), + }, }, ), ( "brown_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 59, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 59, 31]), + }, }, ), ( "brown_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 84, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 84, 53]), + }, }, ), ( "brown_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 106, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 106, 85]), + }, }, ), ( "brown_mushroom", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brown_mushroom_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 111, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 111, 81]), + }, }, ), ( "brown_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 66, 35]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 66, 35]), + }, }, ), ( "brown_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 76, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 76, 51]), + }, }, ), ( "brown_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 73, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 73, 48]), + }, }, ), ( "brown_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 51, 35]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 51, 35]), + }, }, ), ( "brown_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "brown_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 71, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 71, 40]), + }, }, ), ( "bubble_column", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: Color([177, 177, 177]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Water}), + color: Color([177, 177, 177]), + }, }, ), ( "bubble_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bubble_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 26, 162]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 26, 162]), + }, }, ), ( "bubble_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "bubble_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "budding_amethyst", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 96, 186]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 96, 186]), + }, }, ), ( "cactus", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 127, 43]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 127, 43]), + }, }, ), ( "cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "calcite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 224, 220]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 224, 220]), + }, }, ), ( "calibrated_sculk_sensor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([27, 79, 100]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([27, 79, 100]), + }, }, ), ( "campfire", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 88, 54]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 88, 54]), + }, }, ), ( "candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "carrots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 124, 37]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 124, 37]), + }, }, ), ( "cartography_table", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 87, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 87, 67]), + }, }, ), ( "carved_pumpkin", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 118, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 118, 24]), + }, }, ), ( "cauldron", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, }, ), ( "cave_air", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cave_vines", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 109, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 109, 40]), + }, }, ), ( "cave_vines_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 101, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 101, 38]), + }, }, ), ( "chain", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "chain_command_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 161, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 161, 147]), + }, }, ), ( "cherry_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cherry_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 170, 164]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 170, 164]), + }, }, ), ( "cherry_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cherry_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 172, 194]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 172, 194]), + }, }, ), ( "cherry_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([185, 141, 137]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([185, 141, 137]), + }, }, ), ( "cherry_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cherry_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, }, ), ( "cherry_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cherry_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cherry_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 33, 44]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 33, 44]), + }, }, ), ( "chest", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "chipped_anvil", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, }, ), ( "chiseled_bookshelf", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 144, 88]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 144, 88]), + }, }, ), ( "chiseled_deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 54]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 54]), + }, }, ), ( "chiseled_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 23, 28]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 23, 28]), + }, }, ), ( "chiseled_polished_blackstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "chiseled_quartz_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([231, 226, 218]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([231, 226, 218]), + }, }, ), ( "chiseled_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "chiseled_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "chiseled_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 118, 119]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 118, 119]), + }, }, ), ( "chorus_flower", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([151, 120, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([151, 120, 151]), + }, }, ), ( "chorus_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 57, 93]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 57, 93]), + }, }, ), ( "clay", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 166, 179]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 166, 179]), + }, }, ), ( "coal_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([16, 15, 15]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([16, 15, 15]), + }, }, ), ( "coal_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 105, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 105, 105]), + }, }, ), ( "coarse_dirt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 85, 59]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 85, 59]), + }, }, ), ( "cobbled_deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, }, ), ( "cobbled_deepslate_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, }, ), ( "cobbled_deepslate_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, }, ), ( "cobbled_deepslate_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 77, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 77, 80]), + }, }, ), ( "cobblestone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, }, ), ( "cobblestone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, }, ), ( "cobblestone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, }, ), ( "cobblestone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, }, ), ( "cobweb", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 233, 234]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 233, 234]), + }, }, ), ( "cocoa", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 91, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 91, 40]), + }, }, ), ( "command_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 136, 108]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 136, 108]), + }, }, ), ( "comparator", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 161, 159]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 161, 159]), + }, }, ), ( "composter", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 61, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 61, 23]), + }, }, ), ( "conduit", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([159, 139, 113]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([159, 139, 113]), + }, }, ), ( "copper_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 107, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 107, 79]), + }, }, ), ( "copper_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 125, 120]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 125, 120]), + }, }, ), ( "cornflower", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cracked_deepslate_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([64, 64, 65]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([64, 64, 65]), + }, }, ), ( "cracked_deepslate_tiles", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 52, 52]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 52, 52]), + }, }, ), ( "cracked_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([40, 20, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([40, 20, 23]), + }, }, ), ( "cracked_polished_blackstone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 37, 43]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 37, 43]), + }, }, ), ( "cracked_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 118]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 118]), + }, }, ), ( "crafting_table", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 73, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 73, 42]), + }, }, ), ( "creeper_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "creeper_wall_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crimson_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crimson_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 54, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 54, 79]), + }, }, ), ( "crimson_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_fungus", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crimson_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crimson_hyphae", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([92, 25, 29]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 25, 29]), + }, }, ), ( "crimson_nylium", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 31, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 31, 31]), + }, }, ), ( "crimson_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([126, 8, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([126, 8, 41]), + }, }, ), ( "crimson_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 48, 70]), + }, }, ), ( "crimson_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 49, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 49, 70]), + }, }, ), ( "crimson_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 50, 72]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 50, 72]), + }, }, ), ( "crimson_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crimson_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "crying_obsidian", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([32, 10, 60]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([32, 10, 60]), + }, }, ), ( "cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "cut_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "cut_red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "cut_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "cut_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "cyan_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cyan_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cyan_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cyan_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "cyan_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 137, 145]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 137, 145]), + }, }, ), ( "cyan_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 119, 136]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 119, 136]), + }, }, ), ( "cyan_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([36, 147, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([36, 147, 157]), + }, }, ), ( "cyan_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 118, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 118, 125]), + }, }, ), ( "cyan_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 121, 135]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 121, 135]), + }, }, ), ( "cyan_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 127, 153]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 127, 153]), + }, }, ), ( "cyan_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 122, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 122, 147]), + }, }, ), ( "cyan_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([86, 91, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([86, 91, 91]), + }, }, ), ( "cyan_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "cyan_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([21, 137, 145]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([21, 137, 145]), + }, }, ), ( "damaged_anvil", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 72]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 72]), + }, }, ), ( "dandelion", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dark_oak_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dark_oak_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 51, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 51, 25]), + }, }, ), ( "dark_oak_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dark_oak_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([150, 150, 150]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([150, 150, 150]), + }, }, ), ( "dark_oak_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([67, 45, 22]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([67, 45, 22]), + }, }, ), ( "dark_oak_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([61, 90, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([61, 90, 30]), + }, }, ), ( "dark_oak_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 43, 20]), + }, }, ), ( "dark_oak_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 49, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 49, 23]), + }, }, ), ( "dark_oak_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dark_oak_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dark_oak_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([60, 46, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([60, 46, 26]), + }, }, ), ( "dark_prismarine", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, }, ), ( "dark_prismarine_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, }, ), ( "dark_prismarine_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 91, 75]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 91, 75]), + }, }, ), ( "daylight_detector", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 116, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 116, 94]), + }, }, ), ( "dead_brain_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_brain_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 117, 114]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 117, 114]), + }, }, ), ( "dead_brain_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_brain_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_bubble_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_bubble_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 123, 119]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 123, 119]), + }, }, ), ( "dead_bubble_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_bubble_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 78, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 78, 40]), + }, }, ), ( "dead_fire_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_fire_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 123, 119]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 123, 119]), + }, }, ), ( "dead_fire_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_fire_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_horn_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_horn_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([133, 126, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([133, 126, 122]), + }, }, ), ( "dead_horn_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_horn_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_tube_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_tube_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([130, 123, 119]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([130, 123, 119]), + }, }, ), ( "dead_tube_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dead_tube_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "decorated_pot", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 68, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 68, 53]), + }, }, ), ( "deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 82]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 82]), + }, }, ), ( "deepslate_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, }, ), ( "deepslate_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, }, ), ( "deepslate_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, }, ), ( "deepslate_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 70, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 70, 71]), + }, }, ), ( "deepslate_coal_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 74, 76]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 74, 76]), + }, }, ), ( "deepslate_copper_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([92, 93, 89]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 93, 89]), + }, }, ), ( "deepslate_diamond_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 106, 106]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 106, 106]), + }, }, ), ( "deepslate_emerald_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([78, 104, 87]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([78, 104, 87]), + }, }, ), ( "deepslate_gold_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 102, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 102, 78]), + }, }, ), ( "deepslate_iron_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 99, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 99, 94]), + }, }, ), ( "deepslate_lapis_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 90, 115]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 90, 115]), + }, }, ), ( "deepslate_redstone_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([104, 73, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 73, 74]), + }, }, ), ( "deepslate_tile_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, }, ), ( "deepslate_tile_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, }, ), ( "deepslate_tile_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, }, ), ( "deepslate_tiles", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 54, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 54, 55]), + }, }, ), ( "detector_rail", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 104, 90]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 104, 90]), + }, }, ), ( "diamond_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([98, 237, 228]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 237, 228]), + }, }, ), ( "diamond_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 141, 140]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 141, 140]), + }, }, ), ( "diorite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, }, ), ( "diorite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, }, ), ( "diorite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, }, ), ( "diorite_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 188, 188]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 188, 188]), + }, }, ), ( "dirt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 96, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 96, 67]), + }, }, ), ( "dirt_path", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 121, 65]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 121, 65]), + }, }, ), ( "dispenser", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, }, ), ( "dragon_egg", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([12, 9, 15]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([12, 9, 15]), + }, }, ), ( "dragon_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dragon_wall_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "dried_kelp_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([50, 58, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([50, 58, 38]), + }, }, ), ( "dripstone_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([134, 107, 92]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([134, 107, 92]), + }, }, ), ( "dropper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, }, ), ( "emerald_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([42, 203, 87]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([42, 203, 87]), + }, }, ), ( "emerald_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 136, 115]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 136, 115]), + }, }, ), ( "enchanting_table", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([128, 75, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([128, 75, 85]), + }, }, ), ( "end_gateway", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, }, ), ( "end_portal", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, }, ), ( "end_portal_frame", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([91, 120, 97]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([91, 120, 97]), + }, }, ), ( "end_rod", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "end_stone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([219, 222, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([219, 222, 158]), + }, }, ), ( "end_stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, }, ), ( "end_stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, }, ), ( "end_stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, }, ), ( "end_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([218, 224, 162]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([218, 224, 162]), + }, }, ), ( "ender_chest", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, }, ), ( "exposed_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 125, 103]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 103]), + }, }, ), ( "exposed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "exposed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "exposed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "farmland", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 44, 15]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 44, 15]), + }, }, ), ( "fern", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "fire", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([211, 140, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([211, 140, 53]), + }, }, ), ( "fire_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "fire_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 35, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 35, 46]), + }, }, ), ( "fire_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "fire_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "fletching_table", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([197, 180, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([197, 180, 133]), + }, }, ), ( "flower_pot", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 68, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 68, 53]), + }, }, ), ( "flowering_azalea", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 121, 64]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 121, 64]), + }, }, ), ( "flowering_azalea_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 111, 60]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 111, 60]), + }, }, ), ( "frogspawn", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 90, 82]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 90, 82]), + }, }, ), ( "frosted_ice", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 181, 252]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 181, 252]), + }, }, ), ( "furnace", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 109, 109]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 109, 109]), + }, }, ), ( "gilded_blackstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([55, 42, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([55, 42, 38]), + }, }, ), ( "glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 213, 219]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 213, 219]), + }, }, ), ( "glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([170, 210, 217]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([170, 210, 217]), + }, }, ), ( "glow_item_frame", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "glow_lichen", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "glowstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 131, 84]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 131, 84]), + }, }, ), ( "gold_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 208, 61]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 208, 61]), + }, }, ), ( "gold_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([145, 133, 106]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([145, 133, 106]), + }, }, ), ( "granite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, }, ), ( "granite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, }, ), ( "granite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, }, ), ( "granite_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 103, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 103, 85]), + }, }, ), ( "grass", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "grass_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([147, 147, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([147, 147, 147]), + }, }, ), ( "grass_path", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 121, 65]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 121, 65]), + }, }, ), ( "gravel", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 127, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 127, 126]), + }, }, ), ( "gray_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "gray_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "gray_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "gray_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "gray_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([62, 68, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([62, 68, 71]), + }, }, ), ( "gray_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([54, 57, 61]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 57, 61]), + }, }, ), ( "gray_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 81, 84]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 81, 84]), + }, }, ), ( "gray_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 90, 93]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 90, 93]), + }, }, ), ( "gray_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([55, 58, 62]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([55, 58, 62]), + }, }, ), ( "gray_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 76, 76]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 76, 76]), + }, }, ), ( "gray_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 73, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 73, 73]), + }, }, ), ( "gray_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 42, 35]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 42, 35]), + }, }, ), ( "gray_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "gray_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([62, 68, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([62, 68, 71]), + }, }, ), ( "green_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "green_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "green_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "green_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "green_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 109, 27]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 109, 27]), + }, }, ), ( "green_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 91, 36]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 91, 36]), + }, }, ), ( "green_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 119, 44]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 119, 44]), + }, }, ), ( "green_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 142, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 142, 67]), + }, }, ), ( "green_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 100, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 100, 31]), + }, }, ), ( "green_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 127, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 127, 51]), + }, }, ), ( "green_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 122, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 122, 48]), + }, }, ), ( "green_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([76, 83, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([76, 83, 42]), + }, }, ), ( "green_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "green_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 109, 27]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 109, 27]), + }, }, ), ( "grindstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 142]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 142]), + }, }, ), ( "hanging_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 115, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 115, 91]), + }, }, ), ( "hay_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 139, 12]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 139, 12]), + }, }, ), ( "heavy_weighted_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 220, 220]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 220, 220]), + }, }, ), ( "honey_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([251, 185, 52]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([251, 185, 52]), + }, }, ), ( "honeycomb_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 148, 29]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 148, 29]), + }, }, ), ( "hopper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 74, 75]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 74, 75]), + }, }, ), ( "horn_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "horn_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 199, 66]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 199, 66]), + }, }, ), ( "horn_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "horn_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "ice", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([145, 183, 253]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([145, 183, 253]), + }, }, ), ( "infested_chiseled_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 118, 119]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 118, 119]), + }, }, ), ( "infested_cobblestone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 127, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 127, 127]), + }, }, ), ( "infested_cracked_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 118]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 118]), + }, }, ), ( "infested_deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 80, 82]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 80, 82]), + }, }, ), ( "infested_mossy_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, }, ), ( "infested_stone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, }, ), ( "infested_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, }, ), ( "iron_bars", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 139, 135]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 139, 135]), + }, }, ), ( "iron_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([220, 220, 220]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([220, 220, 220]), + }, }, ), ( "iron_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([194, 193, 193]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([194, 193, 193]), + }, }, ), ( "iron_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([136, 129, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([136, 129, 122]), + }, }, ), ( "iron_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([202, 202, 202]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([202, 202, 202]), + }, }, ), ( "item_frame", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "jack_o_lantern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([214, 152, 52]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([214, 152, 52]), + }, }, ), ( "jigsaw", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 69, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 69, 81]), + }, }, ), ( "jukebox", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 64, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 64, 47]), + }, }, ), ( "jungle_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "jungle_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([163, 119, 84]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([163, 119, 84]), + }, }, ), ( "jungle_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "jungle_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([156, 154, 143]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([156, 154, 143]), + }, }, ), ( "jungle_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 109, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 109, 70]), + }, }, ), ( "jungle_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 81, 16]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 81, 16]), + }, }, ), ( "jungle_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 115, 80]), + }, }, ), ( "jungle_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([152, 110, 77]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([152, 110, 77]), + }, }, ), ( "jungle_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "jungle_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "jungle_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 67, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 67, 25]), + }, }, ), ( "kelp", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "kelp_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([86, 130, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([86, 130, 42]), + }, }, ), ( "ladder", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lantern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 91, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 91, 83]), + }, }, ), ( "lapis_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([30, 67, 140]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([30, 67, 140]), + }, }, ), ( "lapis_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 117, 141]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 117, 141]), + }, }, ), ( "large_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "large_fern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([125, 125, 125]), + }, }, ), ( "lava", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([212, 90, 18]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([212, 90, 18]), + }, }, ), ( "lava_cauldron", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, }, ), ( "lectern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([173, 137, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([173, 137, 83]), + }, }, ), ( "lever", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_blue_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_blue_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_blue_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_blue_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "light_blue_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 175, 217]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 175, 217]), + }, }, ), ( "light_blue_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([35, 137, 198]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([35, 137, 198]), + }, }, ), ( "light_blue_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 180, 213]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 180, 213]), + }, }, ), ( "light_blue_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 164, 208]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 164, 208]), + }, }, ), ( "light_blue_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([49, 163, 212]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([49, 163, 212]), + }, }, ), ( "light_blue_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 153, 216]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 153, 216]), + }, }, ), ( "light_blue_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 147, 208]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 147, 208]), + }, }, ), ( "light_blue_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([113, 108, 137]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([113, 108, 137]), + }, }, ), ( "light_blue_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_blue_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 175, 217]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 175, 217]), + }, }, ), ( "light_gray_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_gray_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_gray_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_gray_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "light_gray_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 134]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 134]), + }, }, ), ( "light_gray_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 115]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 115]), + }, }, ), ( "light_gray_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 154, 148]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 154, 148]), + }, }, ), ( "light_gray_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([144, 166, 167]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([144, 166, 167]), + }, }, ), ( "light_gray_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 124, 115]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 124, 115]), + }, }, ), ( "light_gray_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 153, 153]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 153, 153]), + }, }, ), ( "light_gray_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 147, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 147, 147]), + }, }, ), ( "light_gray_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([135, 106, 97]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 106, 97]), + }, }, ), ( "light_gray_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "light_gray_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 142, 134]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 142, 134]), + }, }, ), ( "light_weighted_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 208, 61]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 208, 61]), + }, }, ), ( "lightning_rod", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lilac", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 125, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 125, 147]), + }, }, ), ( "lily_of_the_valley", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lily_pad", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([133, 133, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([133, 133, 133]), + }, }, ), ( "lime_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lime_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lime_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lime_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "lime_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 185, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 185, 25]), + }, }, ), ( "lime_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([94, 168, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([94, 168, 24]), + }, }, ), ( "lime_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 189, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 189, 41]), + }, }, ), ( "lime_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 197, 55]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 197, 55]), + }, }, ), ( "lime_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 172, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 172, 23]), + }, }, ), ( "lime_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 204, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 204, 25]), + }, }, ), ( "lime_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 196, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 196, 24]), + }, }, ), ( "lime_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 117, 52]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 117, 52]), + }, }, ), ( "lime_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "lime_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 185, 25]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 185, 25]), + }, }, ), ( "lodestone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 149, 152]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 149, 152]), + }, }, ), ( "loom", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 119, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 119, 91]), + }, }, ), ( "magenta_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "magenta_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "magenta_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "magenta_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "magenta_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([189, 68, 179]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([189, 68, 179]), + }, }, ), ( "magenta_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 48, 159]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 48, 159]), + }, }, ), ( "magenta_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 83, 184]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 83, 184]), + }, }, ), ( "magenta_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([208, 100, 191]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([208, 100, 191]), + }, }, ), ( "magenta_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([173, 54, 163]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([173, 54, 163]), + }, }, ), ( "magenta_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 76, 216]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 76, 216]), + }, }, ), ( "magenta_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 73, 208]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 73, 208]), + }, }, ), ( "magenta_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([149, 88, 108]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([149, 88, 108]), + }, }, ), ( "magenta_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "magenta_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([189, 68, 179]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([189, 68, 179]), + }, }, ), ( "magma_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 63, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 63, 31]), + }, }, ), ( "mangrove_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "mangrove_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 48, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 48, 46]), + }, }, ), ( "mangrove_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "mangrove_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([129, 128, 128]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([129, 128, 128]), + }, }, ), ( "mangrove_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([102, 48, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([102, 48, 42]), + }, }, ), ( "mangrove_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_propagule", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 174, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 174, 83]), + }, }, ), ( "mangrove_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 59, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 59, 38]), + }, }, ), ( "mangrove_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 54, 48]), + }, }, ), ( "mangrove_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 46, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 46, 42]), + }, }, ), ( "mangrove_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "mangrove_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "mangrove_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([83, 66, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 66, 41]), + }, }, ), ( "medium_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "melon", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 144, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 144, 30]), + }, }, ), ( "melon_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([153, 153, 153]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([153, 153, 153]), + }, }, ), ( "moss_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 109, 45]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 109, 45]), + }, }, ), ( "moss_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 109, 45]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 109, 45]), + }, }, ), ( "mossy_cobblestone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, }, ), ( "mossy_cobblestone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, }, ), ( "mossy_cobblestone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, }, ), ( "mossy_cobblestone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([110, 118, 94]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 118, 94]), + }, }, ), ( "mossy_stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, }, ), ( "mossy_stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, }, ), ( "mossy_stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, }, ), ( "mossy_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 121, 105]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 121, 105]), + }, }, ), ( "moving_piston", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "mud", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([60, 57, 60]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([60, 57, 60]), + }, }, ), ( "mud_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, }, ), ( "mud_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, }, ), ( "mud_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, }, ), ( "mud_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 103, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 103, 79]), + }, }, ), ( "muddy_mangrove_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([70, 58, 45]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 58, 45]), + }, }, ), ( "mushroom_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([203, 196, 185]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([203, 196, 185]), + }, }, ), ( "mycelium", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 98, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 98, 101]), + }, }, ), ( "nether_brick_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, }, ), ( "nether_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, }, ), ( "nether_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, }, ), ( "nether_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, }, ), ( "nether_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 21, 26]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 21, 26]), + }, }, ), ( "nether_gold_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 54, 42]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 54, 42]), + }, }, ), ( "nether_portal", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 11, 192]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 11, 192]), + }, }, ), ( "nether_quartz_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 65, 62]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([117, 65, 62]), + }, }, ), ( "nether_sprouts", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([19, 151, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([19, 151, 133]), + }, }, ), ( "nether_wart", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 18, 19]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 18, 19]), + }, }, ), ( "nether_wart_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 2, 2]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 2, 2]), + }, }, ), ( "netherite_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 61, 63]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([66, 61, 63]), + }, }, ), ( "netherrack", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([97, 38, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 38, 38]), + }, }, ), ( "note_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 58, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 58, 40]), + }, }, ), ( "oak_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "oak_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 110, 66]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 110, 66]), + }, }, ), ( "oak_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "oak_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: Color([144, 144, 144]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: Color([144, 144, 144]), + }, }, ), ( "oak_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([151, 121, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([151, 121, 73]), + }, }, ), ( "oak_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 106, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 106, 40]), + }, }, ), ( "oak_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "oak_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([124, 99, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 99, 56]), + }, }, ), ( "oak_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "oak_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "oak_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 85, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 85, 50]), + }, }, ), ( "observer", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([98, 98, 98]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 98, 98]), + }, }, ), ( "obsidian", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 10, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 10, 24]), + }, }, ), ( "ochre_froglight", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([250, 245, 206]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([250, 245, 206]), + }, }, ), ( "orange_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "orange_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "orange_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "orange_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "orange_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 118, 19]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 118, 19]), + }, }, ), ( "orange_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([224, 97, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([224, 97, 0]), + }, }, ), ( "orange_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([227, 131, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 131, 31]), + }, }, ), ( "orange_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 147, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 147, 91]), + }, }, ), ( "orange_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 106, 8]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 106, 8]), + }, }, ), ( "orange_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 127, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 127, 51]), + }, }, ), ( "orange_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([208, 122, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([208, 122, 48]), + }, }, ), ( "orange_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 83, 37]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 83, 37]), + }, }, ), ( "orange_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "orange_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "orange_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 118, 19]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 118, 19]), + }, }, ), ( "oxeye_daisy", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "oxidized_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([82, 162, 132]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 162, 132]), + }, }, ), ( "oxidized_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "oxidized_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "oxidized_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "packed_ice", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([141, 180, 250]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([141, 180, 250]), + }, }, ), ( "packed_mud", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 106, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 106, 79]), + }, }, ), ( "pearlescent_froglight", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([245, 240, 239]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([245, 240, 239]), + }, }, ), ( "peony", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 126, 139]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 126, 139]), + }, }, ), ( "petrified_oak_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "piglin_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "piglin_wall_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "pink_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([237, 141, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([237, 141, 172]), + }, }, ), ( "pink_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([213, 101, 142]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([213, 101, 142]), + }, }, ), ( "pink_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 153, 181]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 153, 181]), + }, }, ), ( "pink_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 154, 181]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 154, 181]), + }, }, ), ( "pink_petals", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([230, 121, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([230, 121, 157]), + }, }, ), ( "pink_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([242, 127, 165]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([242, 127, 165]), + }, }, ), ( "pink_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 122, 159]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 122, 159]), + }, }, ), ( "pink_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 78, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 78, 78]), + }, }, ), ( "pink_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "pink_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([237, 141, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([237, 141, 172]), + }, }, ), ( "piston", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 104, 96]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 104, 96]), + }, }, ), ( "piston_head", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 127, 85]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 127, 85]), + }, }, ), ( "pitcher_crop", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 165, 103]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 165, 103]), + }, }, ), ( "pitcher_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 144, 189]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 144, 189]), + }, }, ), ( "player_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "player_wall_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "podzol", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([91, 63, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([91, 63, 24]), + }, }, ), ( "pointed_dripstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 102, 89]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 102, 89]), + }, }, ), ( "polished_andesite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, }, ), ( "polished_andesite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, }, ), ( "polished_andesite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 134, 133]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 134, 133]), + }, }, ), ( "polished_basalt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 98, 100]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 98, 100]), + }, }, ), ( "polished_blackstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "polished_blackstone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, }, ), ( "polished_blackstone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, }, ), ( "polished_blackstone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, }, ), ( "polished_blackstone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([48, 42, 49]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([48, 42, 49]), + }, }, ), ( "polished_blackstone_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "polished_blackstone_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "polished_blackstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "polished_blackstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "polished_blackstone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 48, 56]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 48, 56]), + }, }, ), ( "polished_deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, }, ), ( "polished_deepslate_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, }, ), ( "polished_deepslate_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, }, ), ( "polished_deepslate_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 73]), + }, }, ), ( "polished_diorite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, }, ), ( "polished_diorite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, }, ), ( "polished_diorite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 193, 194]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 193, 194]), + }, }, ), ( "polished_granite", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, }, ), ( "polished_granite_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, }, ), ( "polished_granite_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 106, 89]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 106, 89]), + }, }, ), ( "poppy", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "potatoes", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([84, 135, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([84, 135, 47]), + }, }, ), ( "potted_acacia_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 117, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 117, 23]), + }, }, ), ( "potted_allium", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 137, 183]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 137, 183]), + }, }, ), ( "potted_azalea_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 124, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([101, 124, 47]), + }, }, ), ( "potted_azure_bluet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 204, 127]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 204, 127]), + }, }, ), ( "potted_bamboo", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 144, 19]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 144, 19]), + }, }, ), ( "potted_birch_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 160, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 160, 79]), + }, }, ), ( "potted_blue_orchid", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 162, 168]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 162, 168]), + }, }, ), ( "potted_brown_mushroom", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 116, 92]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 116, 92]), + }, }, ), ( "potted_cactus", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 127, 43]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 127, 43]), + }, }, ), ( "potted_cherry_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([164, 117, 143]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([164, 117, 143]), + }, }, ), ( "potted_cornflower", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 121, 146]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 121, 146]), + }, }, ), ( "potted_crimson_fungus", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([141, 44, 29]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([141, 44, 29]), + }, }, ), ( "potted_crimson_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 8, 41]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 8, 41]), + }, }, ), ( "potted_dandelion", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 172, 43]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 172, 43]), + }, }, ), ( "potted_dark_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([61, 90, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([61, 90, 30]), + }, }, ), ( "potted_dead_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([107, 78, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([107, 78, 40]), + }, }, ), ( "potted_fern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([124, 124, 124]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([124, 124, 124]), + }, }, ), ( "potted_flowering_azalea_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([112, 121, 64]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 121, 64]), + }, }, ), ( "potted_jungle_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 81, 16]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 81, 16]), + }, }, ), ( "potted_lily_of_the_valley", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 174, 95]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 174, 95]), + }, }, ), ( "potted_mangrove_propagule", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([96, 174, 83]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([96, 174, 83]), + }, }, ), ( "potted_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([77, 106, 40]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([77, 106, 40]), + }, }, ), ( "potted_orange_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 142, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 142, 30]), + }, }, ), ( "potted_oxeye_daisy", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([179, 202, 143]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([179, 202, 143]), + }, }, ), ( "potted_pink_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 157, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 157, 78]), + }, }, ), ( "potted_poppy", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([128, 64, 37]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([128, 64, 37]), + }, }, ), ( "potted_red_mushroom", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([216, 75, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 75, 67]), + }, }, ), ( "potted_red_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([89, 128, 32]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 128, 32]), + }, }, ), ( "potted_spruce_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 60, 36]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 60, 36]), + }, }, ), ( "potted_torchflower", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([100, 101, 77]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([100, 101, 77]), + }, }, ), ( "potted_warped_fungus", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([74, 109, 87]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([74, 109, 87]), + }, }, ), ( "potted_warped_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 136, 123]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 136, 123]), + }, }, ), ( "potted_white_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([93, 164, 71]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([93, 164, 71]), + }, }, ), ( "potted_wither_rose", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([41, 44, 23]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([41, 44, 23]), + }, }, ), ( "powder_snow", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 253, 253]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 253, 253]), + }, }, ), ( "powder_snow_cauldron", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, }, ), ( "powered_rail", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 109, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 109, 74]), + }, }, ), ( "prismarine", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, }, ), ( "prismarine_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, }, ), ( "prismarine_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, }, ), ( "prismarine_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 171, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 171, 158]), + }, }, ), ( "prismarine_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, }, ), ( "prismarine_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, }, ), ( "prismarine_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([99, 156, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([99, 156, 151]), + }, }, ), ( "pumpkin", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 118, 24]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 118, 24]), + }, }, ), ( "pumpkin_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([154, 154, 154]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([154, 154, 154]), + }, }, ), ( "purple_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "purple_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "purple_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "purple_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "purple_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 42, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 42, 172]), + }, }, ), ( "purple_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([100, 31, 156]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([100, 31, 156]), + }, }, ), ( "purple_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 55, 177]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 55, 177]), + }, }, ), ( "purple_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 47, 152]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 47, 152]), + }, }, ), ( "purple_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 32, 156]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 32, 156]), + }, }, ), ( "purple_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([127, 63, 178]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([127, 63, 178]), + }, }, ), ( "purple_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 61, 171]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 61, 171]), + }, }, ), ( "purple_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([118, 70, 86]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([118, 70, 86]), + }, }, ), ( "purple_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "purple_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 42, 172]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 42, 172]), + }, }, ), ( "purpur_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, }, ), ( "purpur_pillar", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 129, 171]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 129, 171]), + }, }, ), ( "purpur_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, }, ), ( "purpur_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([169, 125, 169]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([169, 125, 169]), + }, }, ), ( "quartz_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "quartz_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 229, 221]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 229, 221]), + }, }, ), ( "quartz_pillar", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 230, 224]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 230, 224]), + }, }, ), ( "quartz_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "quartz_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "rail", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 111, 88]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 111, 88]), + }, }, ), ( "raw_copper_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 105, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 105, 79]), + }, }, ), ( "raw_gold_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 169, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 169, 46]), + }, }, ), ( "raw_iron_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 135, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 135, 107]), + }, }, ), ( "red_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "red_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 39, 34]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 39, 34]), + }, }, ), ( "red_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 32, 32]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 32, 32]), + }, }, ), ( "red_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 54, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([168, 54, 50]), + }, }, ), ( "red_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 59, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 59, 53]), + }, }, ), ( "red_mushroom", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_mushroom_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([200, 46, 45]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([200, 46, 45]), + }, }, ), ( "red_nether_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, }, ), ( "red_nether_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, }, ), ( "red_nether_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, }, ), ( "red_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([69, 7, 9]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([69, 7, 9]), + }, }, ), ( "red_sand", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([190, 102, 33]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 102, 33]), + }, }, ), ( "red_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "red_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "red_sandstone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "red_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 31, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 31, 30]), + }, }, ), ( "red_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([153, 51, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([153, 51, 51]), + }, }, ), ( "red_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([147, 48, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([147, 48, 48]), + }, }, ), ( "red_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([143, 61, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([143, 61, 46]), + }, }, ), ( "red_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "red_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 39, 34]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 39, 34]), + }, }, ), ( "redstone_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 24, 5]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 24, 5]), + }, }, ), ( "redstone_lamp", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([95, 54, 30]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([95, 54, 30]), + }, }, ), ( "redstone_ore", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([140, 109, 109]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([140, 109, 109]), + }, }, ), ( "redstone_torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "redstone_wall_torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "redstone_wire", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([175, 24, 5]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([175, 24, 5]), + }, }, ), ( "reinforced_deepslate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 82, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 82, 78]), + }, }, ), ( "repeater", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 157, 156]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 157, 156]), + }, }, ), ( "repeating_command_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 111, 176]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 111, 176]), + }, }, ), ( "respawn_anchor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 26, 144]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 26, 144]), + }, }, ), ( "rooted_dirt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([144, 103, 76]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([144, 103, 76]), + }, }, ), ( "rose_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([131, 66, 37]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([131, 66, 37]), + }, }, ), ( "sand", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([219, 207, 163]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([219, 207, 163]), + }, }, ), ( "sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "sandstone_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "scaffolding", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([170, 131, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([170, 131, 73]), + }, }, ), ( "sculk", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([12, 29, 36]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([12, 29, 36]), + }, }, ), ( "sculk_catalyst", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([15, 31, 38]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([15, 31, 38]), + }, }, ), ( "sculk_sensor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([7, 70, 84]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([7, 70, 84]), + }, }, ), ( "sculk_shrieker", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([198, 205, 169]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 205, 169]), + }, }, ), ( "sculk_vein", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([7, 48, 57]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([7, 48, 57]), + }, }, ), ( "sea_lantern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([172, 199, 190]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([172, 199, 190]), + }, }, ), ( "sea_pickle", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([90, 97, 39]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([90, 97, 39]), + }, }, ), ( "seagrass", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( @@ -5704,1366 +7330,1756 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ ( "shroomlight", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 146, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 146, 70]), + }, }, ), ( "shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([139, 96, 139]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([139, 96, 139]), + }, }, ), ( "sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "skeleton_skull", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "skeleton_wall_skull", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "slime_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([111, 192, 91]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([111, 192, 91]), + }, }, ), ( "small_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "small_dripleaf", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "smithing_table", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 58, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 58, 70]), + }, }, ), ( "smoker", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([85, 83, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([85, 83, 81]), + }, }, ), ( "smooth_basalt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 72, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 72, 78]), + }, }, ), ( "smooth_quartz", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "smooth_quartz_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "smooth_quartz_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([235, 229, 222]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 229, 222]), + }, }, ), ( "smooth_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "smooth_red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "smooth_red_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([181, 97, 31]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([181, 97, 31]), + }, }, ), ( "smooth_sandstone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "smooth_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "smooth_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([223, 214, 170]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 214, 170]), + }, }, ), ( "smooth_stone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 158, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 158, 158]), + }, }, ), ( "smooth_stone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([158, 158, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([158, 158, 158]), + }, }, ), ( "sniffer_egg", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([135, 105, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 105, 67]), + }, }, ), ( "snow", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([249, 254, 254]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([249, 254, 254]), + }, }, ), ( "snow_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([249, 254, 254]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([249, 254, 254]), + }, }, ), ( "soul_campfire", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([80, 204, 208]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([80, 204, 208]), + }, }, ), ( "soul_fire", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([51, 192, 197]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([51, 192, 197]), + }, }, ), ( "soul_lantern", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([71, 99, 114]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([71, 99, 114]), + }, }, ), ( "soul_sand", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([81, 62, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([81, 62, 50]), + }, }, ), ( "soul_soil", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([75, 57, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([75, 57, 46]), + }, }, ), ( "soul_torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "soul_wall_torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "spawner", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([36, 46, 62]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([36, 46, 62]), + }, }, ), ( "sponge", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([195, 192, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([195, 192, 74]), + }, }, ), ( "spore_blossom", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([206, 96, 158]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([206, 96, 158]), + }, }, ), ( "spruce_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "spruce_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([106, 80, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 80, 48]), + }, }, ), ( "spruce_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "spruce_leaves", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), - color: Color([126, 126, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), + color: Color([126, 126, 126]), + }, }, ), ( "spruce_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 80, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 80, 46]), + }, }, ), ( "spruce_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_sapling", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 60, 36]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 60, 36]), + }, }, ), ( "spruce_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([114, 84, 48]), + }, }, ), ( "spruce_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([103, 79, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([103, 79, 47]), + }, }, ), ( "spruce_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "spruce_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "spruce_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 37, 16]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 37, 16]), + }, }, ), ( "sticky_piston", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 104, 96]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 104, 96]), + }, }, ), ( "stone", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, }, ), ( "stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, }, ), ( "stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, }, ), ( "stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, }, ), ( "stone_bricks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([122, 121, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 121, 122]), + }, }, ), ( "stone_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "stone_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, }, ), ( "stone_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, }, ), ( "stone_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([125, 125, 125]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([125, 125, 125]), + }, }, ), ( "stonecutter", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([123, 118, 111]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([123, 118, 111]), + }, }, ), ( "stripped_acacia_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 91, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 91, 51]), + }, }, ), ( "stripped_acacia_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([174, 92, 59]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([174, 92, 59]), + }, }, ), ( "stripped_bamboo_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([178, 158, 72]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 158, 72]), + }, }, ), ( "stripped_birch_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 171, 116]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 171, 116]), + }, }, ), ( "stripped_birch_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([196, 176, 118]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([196, 176, 118]), + }, }, ), ( "stripped_cherry_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 164, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 164, 157]), + }, }, ), ( "stripped_cherry_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([215, 145, 148]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([215, 145, 148]), + }, }, ), ( "stripped_crimson_hyphae", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([137, 57, 90]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([137, 57, 90]), + }, }, ), ( "stripped_crimson_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([121, 56, 82]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([121, 56, 82]), + }, }, ), ( "stripped_dark_oak_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([65, 44, 22]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([65, 44, 22]), + }, }, ), ( "stripped_dark_oak_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([72, 56, 36]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([72, 56, 36]), + }, }, ), ( "stripped_jungle_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([165, 122, 81]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([165, 122, 81]), + }, }, ), ( "stripped_jungle_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 132, 84]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 132, 84]), + }, }, ), ( "stripped_mangrove_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 43, 43]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 43, 43]), + }, }, ), ( "stripped_mangrove_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([119, 54, 47]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([119, 54, 47]), + }, }, ), ( "stripped_oak_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 129, 77]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([160, 129, 77]), + }, }, ), ( "stripped_oak_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([177, 144, 86]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([177, 144, 86]), + }, }, ), ( "stripped_spruce_log", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([105, 80, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([105, 80, 46]), + }, }, ), ( "stripped_spruce_wood", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([115, 89, 52]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([115, 89, 52]), + }, }, ), ( "stripped_warped_hyphae", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([57, 150, 147]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([57, 150, 147]), + }, }, ), ( "stripped_warped_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([52, 128, 124]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([52, 128, 124]), + }, }, ), ( "structure_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([88, 74, 90]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([88, 74, 90]), + }, }, ), ( "structure_void", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "sugar_cane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([148, 192, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([148, 192, 101]), + }, }, ), ( "sunflower", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 196, 54]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 196, 54]), + }, }, ), ( "suspicious_gravel", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([129, 125, 124]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 125, 124]), + }, }, ), ( "suspicious_sand", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([217, 204, 159]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([217, 204, 159]), + }, }, ), ( "sweet_berry_bush", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([68, 77, 50]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([68, 77, 50]), + }, }, ), ( "tall_grass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([151, 149, 151]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([151, 149, 151]), + }, }, ), ( "tall_seagrass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([59, 139, 14]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([59, 139, 14]), + }, }, ), ( "target", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 170, 157]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 170, 157]), + }, }, ), ( "terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([152, 94, 67]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([152, 94, 67]), + }, }, ), ( "tinted_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 38, 46]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 38, 46]), + }, }, ), ( "tnt", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([142, 62, 53]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([142, 62, 53]), + }, }, ), ( "torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "torchflower", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "torchflower_crop", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "trapped_chest", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([162, 130, 78]), + }, }, ), ( "tripwire", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "tripwire_hook", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "tube_coral", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "tube_coral_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([49, 87, 206]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([49, 87, 206]), + }, }, ), ( "tube_coral_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "tube_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "tuff", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 109, 102]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 109, 102]), + }, }, ), ( "turtle_egg", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([228, 226, 191]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([228, 226, 191]), + }, }, ), ( "twisting_vines", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 143, 124]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 143, 124]), + }, }, ), ( "twisting_vines_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 135, 122]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 135, 122]), + }, }, ), ( "verdant_froglight", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 244, 228]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 244, 228]), + }, }, ), ( "vine", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: Color([116, 116, 116]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([116, 116, 116]), + }, }, ), ( "void_air", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "wall_torch", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_button", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_door", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([44, 126, 120]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([44, 126, 120]), + }, }, ), ( "warped_fence", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_fence_gate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_fungus", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_hyphae", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([58, 58, 77]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([58, 58, 77]), + }, }, ), ( "warped_nylium", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 114, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 114, 101]), + }, }, ), ( "warped_planks", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_roots", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([20, 138, 124]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([20, 138, 124]), + }, }, ), ( "warped_sign", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([43, 104, 99]), + }, }, ), ( "warped_stem", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([53, 109, 110]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([53, 109, 110]), + }, }, ), ( "warped_trapdoor", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 119, 111]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([47, 119, 111]), + }, }, ), ( "warped_wall_hanging_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_wall_sign", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "warped_wart_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([22, 119, 121]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([22, 119, 121]), + }, }, ), ( "water", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: Color([177, 177, 177]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Water}), + color: Color([177, 177, 177]), + }, }, ), ( "water_cauldron", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([73, 72, 74]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 72, 74]), + }, }, ), ( "waxed_copper_block", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 107, 79]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 107, 79]), + }, }, ), ( "waxed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "waxed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "waxed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([191, 106, 80]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 106, 80]), + }, }, ), ( "waxed_exposed_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([161, 125, 103]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 103]), + }, }, ), ( "waxed_exposed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "waxed_exposed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "waxed_exposed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([154, 121, 101]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 121, 101]), + }, }, ), ( "waxed_oxidized_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([82, 162, 132]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 162, 132]), + }, }, ), ( "waxed_oxidized_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "waxed_oxidized_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "waxed_oxidized_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([79, 153, 126]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([79, 153, 126]), + }, }, ), ( "waxed_weathered_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 153, 110]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, }, ), ( "waxed_weathered_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "waxed_weathered_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "waxed_weathered_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "weathered_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([108, 153, 110]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, }, ), ( "weathered_cut_copper", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "weathered_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "weathered_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 145, 107]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 145, 107]), + }, }, ), ( "weeping_vines", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([104, 1, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 1, 0]), + }, }, ), ( "weeping_vines_plant", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([132, 16, 12]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([132, 16, 12]), + }, }, ), ( "wet_sponge", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([171, 181, 70]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([171, 181, 70]), + }, }, ), ( "wheat", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([166, 151, 73]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([166, 151, 73]), + }, }, ), ( "white_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "white_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "white_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "white_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "white_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 236, 236]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 236, 236]), + }, }, ), ( "white_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([207, 213, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([207, 213, 214]), + }, }, ), ( "white_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([225, 227, 227]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([225, 227, 227]), + }, }, ), ( "white_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([188, 212, 202]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([188, 212, 202]), + }, }, ), ( "white_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([215, 220, 221]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([215, 220, 221]), + }, }, ), ( "white_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([255, 255, 255]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([255, 255, 255]), + }, }, ), ( "white_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([246, 246, 246]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([246, 246, 246]), + }, }, ), ( "white_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([209, 178, 161]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([209, 178, 161]), + }, }, ), ( "white_tulip", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "white_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "white_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([233, 236, 236]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([233, 236, 236]), + }, }, ), ( "wither_rose", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "wither_skeleton_skull", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "wither_skeleton_wall_skull", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "yellow_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "yellow_bed", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "yellow_candle", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "yellow_candle_cake", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 222, 214]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 222, 214]), + }, }, ), ( "yellow_carpet", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 197, 39]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 197, 39]), + }, }, ), ( "yellow_concrete", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([240, 175, 21]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([240, 175, 21]), + }, }, ), ( "yellow_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([232, 199, 54]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([232, 199, 54]), + }, }, ), ( "yellow_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([234, 192, 88]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([234, 192, 88]), + }, }, ), ( "yellow_shulker_box", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 188, 29]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 188, 29]), + }, }, ), ( "yellow_stained_glass", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([229, 229, 51]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 229, 51]), + }, }, ), ( "yellow_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([221, 221, 48]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 221, 48]), + }, }, ), ( "yellow_terracotta", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([186, 133, 35]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([186, 133, 35]), + }, }, ), ( "yellow_wall_banner", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "yellow_wool", BlockType { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([248, 197, 39]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([248, 197, 39]), + }, }, ), ( "zombie_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ( "zombie_wall_head", BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, }, ), ]; diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index ad3553f..676b92b 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -42,21 +42,28 @@ pub type Colorf = glam::Vec3; /// A block type specification #[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct BlockType { +pub struct BlockColor { /// Bit set of [BlockFlag]s describing special properties of the block type pub flags: BitFlags, /// Base color of the block type pub color: Color, } -impl BlockType { - /// Checks whether a block type has a given [BlockFlag] set +impl BlockColor { + /// Checks whether a block color has a given [BlockFlag] set #[inline] pub fn is(&self, flag: BlockFlag) -> bool { self.flags.contains(flag) } } +/// A block type specification +#[derive(Debug, Clone)] +pub struct BlockType { + /// Determines the rendered color of the block type + pub block_color: BlockColor, +} + /// Used to look up standard Minecraft block types #[derive(Debug)] pub struct BlockTypes { @@ -70,10 +77,15 @@ impl Default for BlockTypes { fn default() -> Self { let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES .iter() - .map(|(k, v)| (String::from(*k), *v)) + .map(|(k, v)| (String::from(*k), v.clone())) .collect(); let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| { - inner.map(|id| *block_type_map.get(id).expect("Unknown legacy block type")) + inner.map(|id| { + block_type_map + .get(id) + .expect("Unknown legacy block type") + .clone() + }) })); BlockTypes { @@ -86,15 +98,15 @@ impl Default for BlockTypes { impl BlockTypes { /// Resolves a Minecraft 1.13+ string block type ID #[inline] - pub fn get(&self, id: &str) -> Option { + pub fn get(&self, id: &str) -> Option<&BlockType> { let suffix = id.strip_prefix("minecraft:")?; - self.block_type_map.get(suffix).copied() + self.block_type_map.get(suffix) } /// Resolves a Minecraft pre-1.13 numeric block type ID #[inline] - pub fn get_legacy(&self, id: u8, data: u8) -> Option { - Some(self.legacy_block_types[id as usize][data as usize]) + pub fn get_legacy(&self, id: u8, data: u8) -> Option<&BlockType> { + Some(&self.legacy_block_types[id as usize][data as usize]) } } diff --git a/resource/generate.py b/resource/generate.py index 73bb91d..2e6cf21 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -36,11 +36,13 @@ with open(sys.argv[2], 'w') as f: flags.append('Water') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' - print('\t("%s", BlockType { flags: %s, color: Color([%u, %u, %u]) }),' % ( - name, + print('\t("%s", BlockType { ' % name, file=f) + print('\t\tblock_color: BlockColor { flags: %s, color: Color([%u, %u, %u]) },' % ( flags, info['color']['r'], info['color']['g'], info['color']['b'], ), file=f) + print('}),', file=f) + print('];', file=f) diff --git a/src/world/layer.rs b/src/world/layer.rs index ce88107..576dfa4 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use super::chunk::{Chunk, SectionIterItem}; use crate::{ - resource::{Biome, BlockFlag, BlockType}, + resource::{Biome, BlockColor, BlockFlag}, types::*, }; @@ -31,8 +31,8 @@ impl BlockHeight { } } -/// Array optionally storing a [BlockType] for each coordinate of a chunk -pub type BlockArray = LayerBlockArray>; +/// Array optionally storing a [BlockColor] for each coordinate of a chunk +pub type BlockArray = LayerBlockArray>; /// Array optionally storing a biome index for each coordinate of a chunk /// @@ -49,7 +49,7 @@ pub type DepthArray = LayerBlockArray>; /// References to LayerData entries for a single coordinate pair struct LayerEntry<'a> { /// The block type of the referenced entry - block: &'a mut Option, + block: &'a mut Option, /// The biome type of the referenced entry biome: &'a mut Option, /// The block light of the referenced entry @@ -86,7 +86,7 @@ impl<'a> LayerEntry<'a> { let Some(block_type) = section .section .block_at(coords)? - .filter(|block_type| block_type.is(BlockFlag::Opaque)) + .filter(|block_type| block_type.block_color.is(BlockFlag::Opaque)) else { if self.is_empty() { *self.block_light = section.block_light.block_light_at(coords); @@ -96,7 +96,7 @@ impl<'a> LayerEntry<'a> { }; if self.is_empty() { - *self.block = Some(block_type); + *self.block = Some(block_type.block_color); if let Some(biome) = section.biomes.biome_at(section.y, coords)? { let (biome_index, _) = biome_list.insert_full(*biome); *self.biome = NonZeroU16::new( @@ -107,7 +107,7 @@ impl<'a> LayerEntry<'a> { } } - if block_type.is(BlockFlag::Water) { + if block_type.block_color.is(BlockFlag::Water) { return Ok(false); } diff --git a/src/world/section.rs b/src/world/section.rs index 97e0061..62b510b 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -44,7 +44,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { /// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section: Debug { /// Returns the [BlockType] at a coordinate tuple inside the section - fn block_at(&self, coords: SectionBlockCoords) -> Result>; + fn block_at(&self, coords: SectionBlockCoords) -> Result>; } /// Minecraft v1.13+ section block data @@ -53,7 +53,7 @@ pub struct SectionV1_13<'a> { /// Packed block type data block_states: Option<&'a [i64]>, /// List of block types indexed by entries encoded in *block_states* - palette: Vec>, + palette: Vec>, /// Number of bits per block in *block_states* bits: u8, /// Set to true if packed block entries in *block_states* are aligned to i64 @@ -146,7 +146,7 @@ impl<'a> SectionV1_13<'a> { } impl<'a> Section for SectionV1_13<'a> { - fn block_at(&self, coords: SectionBlockCoords) -> Result> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); Ok(*self .palette @@ -189,7 +189,7 @@ impl<'a> SectionV0<'a> { } impl<'a> Section for SectionV0<'a> { - fn block_at(&self, coords: SectionBlockCoords) -> Result> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let offset = coords.offset(); let block = self.blocks[offset] as u8; From abf87e75ee377ba64c32cb19e44b8d7746f51190 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Dec 2023 20:54:26 +0100 Subject: [PATCH 026/152] resource: add sign material to block types --- crates/resource/src/block_types.rs | 3035 ++++++++++++++++++---------- crates/resource/src/lib.rs | 22 +- resource/blocks.json | 182 +- resource/extract.py | 9 +- resource/generate.py | 9 +- 5 files changed, 2207 insertions(+), 1050 deletions(-) diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 87d57c8..f9ec70d 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -2,9084 +2,10095 @@ use enumflags2::make_bitflags; use super::*; -pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ +pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ ( "acacia_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "acacia_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([167, 95, 60]), }, + sign_material: None, }, ), ( "acacia_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("acacia"), }, ), ( "acacia_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: Color([149, 148, 148]), }, + sign_material: None, }, ), ( "acacia_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([150, 88, 55]), }, + sign_material: None, }, ), ( "acacia_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([118, 117, 23]), }, + sign_material: None, }, ), ( "acacia_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: Some("acacia"), }, ), ( "acacia_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 90, 50]), }, + sign_material: None, }, ), ( "acacia_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([156, 87, 51]), }, + sign_material: None, }, ), ( "acacia_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("acacia"), }, ), ( "acacia_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("acacia"), }, ), ( "acacia_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 96, 86]), }, + sign_material: None, }, ), ( "activator_rail", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 87, 74]), }, + sign_material: None, }, ), ( "air", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "allium", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "amethyst_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([133, 97, 191]), }, + sign_material: None, }, ), ( "amethyst_cluster", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([163, 126, 207]), }, + sign_material: None, }, ), ( "ancient_debris", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([94, 66, 58]), }, + sign_material: None, }, ), ( "andesite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 136, 136]), }, + sign_material: None, }, ), ( "andesite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 136, 136]), }, + sign_material: None, }, ), ( "andesite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 136, 136]), }, + sign_material: None, }, ), ( "andesite_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 136, 136]), }, + sign_material: None, }, ), ( "anvil", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 72]), }, + sign_material: None, }, ), ( "attached_melon_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([141, 142, 141]), }, + sign_material: None, }, ), ( "attached_pumpkin_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([139, 139, 139]), }, + sign_material: None, }, ), ( "azalea", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 124, 47]), }, + sign_material: None, }, ), ( "azalea_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([90, 114, 44]), }, + sign_material: None, }, ), ( "azure_bluet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "bamboo", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 144, 19]), }, + sign_material: None, }, ), ( "bamboo_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([139, 141, 62]), }, + sign_material: None, }, ), ( "bamboo_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "bamboo_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 171, 81]), }, + sign_material: None, }, ), ( "bamboo_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("bamboo"), }, ), ( "bamboo_mosaic", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([190, 170, 78]), }, + sign_material: None, }, ), ( "bamboo_mosaic_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([190, 170, 78]), }, + sign_material: None, }, ), ( "bamboo_mosaic_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([190, 170, 78]), }, + sign_material: None, }, ), ( "bamboo_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "bamboo_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: Some("bamboo"), }, ), ( "bamboo_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 173, 80]), }, + sign_material: None, }, ), ( "bamboo_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([198, 179, 85]), }, + sign_material: None, }, ), ( "bamboo_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("bamboo"), }, ), ( "bamboo_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("bamboo"), }, ), ( "barrel", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([134, 100, 58]), }, + sign_material: None, }, ), ( "barrier", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "basalt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 81, 86]), }, + sign_material: None, }, ), ( "beacon", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 220, 215]), }, + sign_material: None, }, ), ( "bedrock", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([85, 85, 85]), }, + sign_material: None, }, ), ( "bee_nest", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([202, 160, 74]), }, + sign_material: None, }, ), ( "beehive", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([180, 146, 90]), }, + sign_material: None, }, ), ( "beetroots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 91, 30]), }, + sign_material: None, }, ), ( "bell", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([253, 235, 110]), }, + sign_material: None, }, ), ( "big_dripleaf", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([111, 141, 51]), }, + sign_material: None, }, ), ( "big_dripleaf_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "birch_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "birch_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([220, 209, 176]), }, + sign_material: None, }, ), ( "birch_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("birch"), }, ), ( "birch_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Birch}), color: Color([130, 129, 130]), }, + sign_material: None, }, ), ( "birch_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 179, 135]), }, + sign_material: None, }, ), ( "birch_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 160, 79]), }, + sign_material: None, }, ), ( "birch_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: Some("birch"), }, ), ( "birch_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 175, 121]), }, + sign_material: None, }, ), ( "birch_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([207, 194, 157]), }, + sign_material: None, }, ), ( "birch_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("birch"), }, ), ( "birch_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("birch"), }, ), ( "birch_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([216, 215, 210]), }, + sign_material: None, }, ), ( "black_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "black_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "black_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "black_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "black_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 21, 25]), }, + sign_material: None, }, ), ( "black_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([8, 10, 15]), }, + sign_material: None, }, ), ( "black_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([25, 26, 31]), }, + sign_material: None, }, ), ( "black_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([67, 30, 32]), }, + sign_material: None, }, ), ( "black_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([25, 25, 29]), }, + sign_material: None, }, ), ( "black_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([25, 25, 25]), }, + sign_material: None, }, ), ( "black_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([24, 24, 24]), }, + sign_material: None, }, ), ( "black_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([37, 22, 16]), }, + sign_material: None, }, ), ( "black_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "black_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 21, 25]), }, + sign_material: None, }, ), ( "blackstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([42, 36, 41]), }, + sign_material: None, }, ), ( "blackstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([42, 36, 41]), }, + sign_material: None, }, ), ( "blackstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([42, 36, 41]), }, + sign_material: None, }, ), ( "blackstone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([42, 36, 41]), }, + sign_material: None, }, ), ( "blast_furnace", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 80, 81]), }, + sign_material: None, }, ), ( "blue_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "blue_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "blue_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "blue_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "blue_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 57, 157]), }, + sign_material: None, }, ), ( "blue_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 46, 143]), }, + sign_material: None, }, ), ( "blue_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 73, 166]), }, + sign_material: None, }, ), ( "blue_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 64, 139]), }, + sign_material: None, }, ), ( "blue_ice", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([116, 167, 253]), }, + sign_material: None, }, ), ( "blue_orchid", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "blue_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 45, 140]), }, + sign_material: None, }, ), ( "blue_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([51, 76, 178]), }, + sign_material: None, }, ), ( "blue_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([48, 73, 171]), }, + sign_material: None, }, ), ( "blue_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([74, 59, 91]), }, + sign_material: None, }, ), ( "blue_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "blue_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 57, 157]), }, + sign_material: None, }, ), ( "bone_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([209, 206, 179]), }, + sign_material: None, }, ), ( "bookshelf", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "brain_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brain_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([207, 91, 159]), }, + sign_material: None, }, ), ( "brain_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brain_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brewing_stand", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 100, 80]), }, + sign_material: None, }, ), ( "brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([150, 97, 83]), }, + sign_material: None, }, ), ( "brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([150, 97, 83]), }, + sign_material: None, }, ), ( "brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([150, 97, 83]), }, + sign_material: None, }, ), ( "bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([150, 97, 83]), }, + sign_material: None, }, ), ( "brown_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brown_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brown_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brown_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "brown_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 71, 40]), }, + sign_material: None, }, ), ( "brown_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([96, 59, 31]), }, + sign_material: None, }, ), ( "brown_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 84, 53]), }, + sign_material: None, }, ), ( "brown_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 106, 85]), }, + sign_material: None, }, ), ( "brown_mushroom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brown_mushroom_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 111, 81]), }, + sign_material: None, }, ), ( "brown_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([106, 66, 35]), }, + sign_material: None, }, ), ( "brown_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([102, 76, 51]), }, + sign_material: None, }, ), ( "brown_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([97, 73, 48]), }, + sign_material: None, }, ), ( "brown_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 51, 35]), }, + sign_material: None, }, ), ( "brown_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "brown_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 71, 40]), }, + sign_material: None, }, ), ( "bubble_column", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: Color([177, 177, 177]), }, + sign_material: None, }, ), ( "bubble_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "bubble_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([165, 26, 162]), }, + sign_material: None, }, ), ( "bubble_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "bubble_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "budding_amethyst", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([132, 96, 186]), }, + sign_material: None, }, ), ( "cactus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([85, 127, 43]), }, + sign_material: None, }, ), ( "cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "calcite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 224, 220]), }, + sign_material: None, }, ), ( "calibrated_sculk_sensor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([27, 79, 100]), }, + sign_material: None, }, ), ( "campfire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 88, 54]), }, + sign_material: None, }, ), ( "candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "carrots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([81, 124, 37]), }, + sign_material: None, }, ), ( "cartography_table", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 87, 67]), }, + sign_material: None, }, ), ( "carved_pumpkin", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([198, 118, 24]), }, + sign_material: None, }, ), ( "cauldron", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 72, 74]), }, + sign_material: None, }, ), ( "cave_air", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cave_vines", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([90, 109, 40]), }, + sign_material: None, }, ), ( "cave_vines_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([88, 101, 38]), }, + sign_material: None, }, ), ( "chain", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "chain_command_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 161, 147]), }, + sign_material: None, }, ), ( "cherry_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cherry_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 170, 164]), }, + sign_material: None, }, ), ( "cherry_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("cherry"), }, ), ( "cherry_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([229, 172, 194]), }, + sign_material: None, }, ), ( "cherry_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([185, 141, 137]), }, + sign_material: None, }, ), ( "cherry_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cherry_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: Some("cherry"), }, ), ( "cherry_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 178, 172]), }, + sign_material: None, }, ), ( "cherry_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("cherry"), }, ), ( "cherry_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("cherry"), }, ), ( "cherry_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 33, 44]), }, + sign_material: None, }, ), ( "chest", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "chipped_anvil", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 72]), }, + sign_material: None, }, ), ( "chiseled_bookshelf", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([178, 144, 88]), }, + sign_material: None, }, ), ( "chiseled_deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 54, 54]), }, + sign_material: None, }, ), ( "chiseled_nether_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 23, 28]), }, + sign_material: None, }, ), ( "chiseled_polished_blackstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "chiseled_quartz_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([231, 226, 218]), }, + sign_material: None, }, ), ( "chiseled_red_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "chiseled_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "chiseled_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 118, 119]), }, + sign_material: None, }, ), ( "chorus_flower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([151, 120, 151]), }, + sign_material: None, }, ), ( "chorus_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 57, 93]), }, + sign_material: None, }, ), ( "clay", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 166, 179]), }, + sign_material: None, }, ), ( "coal_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([16, 15, 15]), }, + sign_material: None, }, ), ( "coal_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([105, 105, 105]), }, + sign_material: None, }, ), ( "coarse_dirt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 85, 59]), }, + sign_material: None, }, ), ( "cobbled_deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 77, 80]), }, + sign_material: None, }, ), ( "cobbled_deepslate_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 77, 80]), }, + sign_material: None, }, ), ( "cobbled_deepslate_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 77, 80]), }, + sign_material: None, }, ), ( "cobbled_deepslate_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 77, 80]), }, + sign_material: None, }, ), ( "cobblestone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 127, 127]), }, + sign_material: None, }, ), ( "cobblestone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 127, 127]), }, + sign_material: None, }, ), ( "cobblestone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 127, 127]), }, + sign_material: None, }, ), ( "cobblestone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 127, 127]), }, + sign_material: None, }, ), ( "cobweb", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([228, 233, 234]), }, + sign_material: None, }, ), ( "cocoa", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 91, 40]), }, + sign_material: None, }, ), ( "command_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 136, 108]), }, + sign_material: None, }, ), ( "comparator", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([166, 161, 159]), }, + sign_material: None, }, ), ( "composter", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([88, 61, 23]), }, + sign_material: None, }, ), ( "conduit", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([159, 139, 113]), }, + sign_material: None, }, ), ( "copper_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 107, 79]), }, + sign_material: None, }, ), ( "copper_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 125, 120]), }, + sign_material: None, }, ), ( "cornflower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cracked_deepslate_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([64, 64, 65]), }, + sign_material: None, }, ), ( "cracked_deepslate_tiles", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([52, 52, 52]), }, + sign_material: None, }, ), ( "cracked_nether_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([40, 20, 23]), }, + sign_material: None, }, ), ( "cracked_polished_blackstone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 37, 43]), }, + sign_material: None, }, ), ( "cracked_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([118, 117, 118]), }, + sign_material: None, }, ), ( "crafting_table", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 73, 42]), }, + sign_material: None, }, ), ( "creeper_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "creeper_wall_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "crimson_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "crimson_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 54, 79]), }, + sign_material: None, }, ), ( "crimson_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_fungus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "crimson_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("crimson"), }, ), ( "crimson_hyphae", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([92, 25, 29]), }, + sign_material: None, }, ), ( "crimson_nylium", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([130, 31, 31]), }, + sign_material: None, }, ), ( "crimson_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([126, 8, 41]), }, + sign_material: None, }, ), ( "crimson_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: Some("crimson"), }, ), ( "crimson_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 48, 70]), }, + sign_material: None, }, ), ( "crimson_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 49, 70]), }, + sign_material: None, }, ), ( "crimson_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 50, 72]), }, + sign_material: None, }, ), ( "crimson_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("crimson"), }, ), ( "crimson_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("crimson"), }, ), ( "crying_obsidian", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([32, 10, 60]), }, + sign_material: None, }, ), ( "cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "cut_red_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "cut_red_sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "cut_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "cut_sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "cyan_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cyan_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cyan_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cyan_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "cyan_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([21, 137, 145]), }, + sign_material: None, }, ), ( "cyan_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([21, 119, 136]), }, + sign_material: None, }, ), ( "cyan_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([36, 147, 157]), }, + sign_material: None, }, ), ( "cyan_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([52, 118, 125]), }, + sign_material: None, }, ), ( "cyan_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 121, 135]), }, + sign_material: None, }, ), ( "cyan_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([76, 127, 153]), }, + sign_material: None, }, ), ( "cyan_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 122, 147]), }, + sign_material: None, }, ), ( "cyan_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([86, 91, 91]), }, + sign_material: None, }, ), ( "cyan_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "cyan_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([21, 137, 145]), }, + sign_material: None, }, ), ( "damaged_anvil", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 72]), }, + sign_material: None, }, ), ( "dandelion", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dark_oak_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dark_oak_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([76, 51, 25]), }, + sign_material: None, }, ), ( "dark_oak_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: Color([150, 150, 150]), }, + sign_material: None, }, ), ( "dark_oak_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([67, 45, 22]), }, + sign_material: None, }, ), ( "dark_oak_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([61, 90, 30]), }, + sign_material: None, }, ), ( "dark_oak_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 43, 20]), }, + sign_material: None, }, ), ( "dark_oak_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([75, 49, 23]), }, + sign_material: None, }, ), ( "dark_oak_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("dark_oak"), }, ), ( "dark_oak_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([60, 46, 26]), }, + sign_material: None, }, ), ( "dark_prismarine", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([51, 91, 75]), }, + sign_material: None, }, ), ( "dark_prismarine_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([51, 91, 75]), }, + sign_material: None, }, ), ( "dark_prismarine_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([51, 91, 75]), }, + sign_material: None, }, ), ( "daylight_detector", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([130, 116, 94]), }, + sign_material: None, }, ), ( "dead_brain_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_brain_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 117, 114]), }, + sign_material: None, }, ), ( "dead_brain_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_brain_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_bubble_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_bubble_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 123, 119]), }, + sign_material: None, }, ), ( "dead_bubble_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_bubble_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([107, 78, 40]), }, + sign_material: None, }, ), ( "dead_fire_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_fire_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 123, 119]), }, + sign_material: None, }, ), ( "dead_fire_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_fire_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_horn_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_horn_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([133, 126, 122]), }, + sign_material: None, }, ), ( "dead_horn_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_horn_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_tube_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_tube_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([130, 123, 119]), }, + sign_material: None, }, ), ( "dead_tube_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dead_tube_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "decorated_pot", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 68, 53]), }, + sign_material: None, }, ), ( "deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 80, 82]), }, + sign_material: None, }, ), ( "deepslate_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 70, 71]), }, + sign_material: None, }, ), ( "deepslate_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 70, 71]), }, + sign_material: None, }, ), ( "deepslate_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 70, 71]), }, + sign_material: None, }, ), ( "deepslate_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 70, 71]), }, + sign_material: None, }, ), ( "deepslate_coal_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([74, 74, 76]), }, + sign_material: None, }, ), ( "deepslate_copper_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([92, 93, 89]), }, + sign_material: None, }, ), ( "deepslate_diamond_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([83, 106, 106]), }, + sign_material: None, }, ), ( "deepslate_emerald_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([78, 104, 87]), }, + sign_material: None, }, ), ( "deepslate_gold_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 102, 78]), }, + sign_material: None, }, ), ( "deepslate_iron_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([106, 99, 94]), }, + sign_material: None, }, ), ( "deepslate_lapis_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 90, 115]), }, + sign_material: None, }, ), ( "deepslate_redstone_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([104, 73, 74]), }, + sign_material: None, }, ), ( "deepslate_tile_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 54, 55]), }, + sign_material: None, }, ), ( "deepslate_tile_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 54, 55]), }, + sign_material: None, }, ), ( "deepslate_tile_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 54, 55]), }, + sign_material: None, }, ), ( "deepslate_tiles", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 54, 55]), }, + sign_material: None, }, ), ( "detector_rail", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([123, 104, 90]), }, + sign_material: None, }, ), ( "diamond_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([98, 237, 228]), }, + sign_material: None, }, ), ( "diamond_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([121, 141, 140]), }, + sign_material: None, }, ), ( "diorite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([188, 188, 188]), }, + sign_material: None, }, ), ( "diorite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([188, 188, 188]), }, + sign_material: None, }, ), ( "diorite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([188, 188, 188]), }, + sign_material: None, }, ), ( "diorite_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([188, 188, 188]), }, + sign_material: None, }, ), ( "dirt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([134, 96, 67]), }, + sign_material: None, }, ), ( "dirt_path", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([148, 121, 65]), }, + sign_material: None, }, ), ( "dispenser", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 109, 109]), }, + sign_material: None, }, ), ( "dragon_egg", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([12, 9, 15]), }, + sign_material: None, }, ), ( "dragon_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dragon_wall_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "dried_kelp_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([50, 58, 38]), }, + sign_material: None, }, ), ( "dripstone_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([134, 107, 92]), }, + sign_material: None, }, ), ( "dropper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 109, 109]), }, + sign_material: None, }, ), ( "emerald_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([42, 203, 87]), }, + sign_material: None, }, ), ( "emerald_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([108, 136, 115]), }, + sign_material: None, }, ), ( "enchanting_table", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([128, 75, 85]), }, + sign_material: None, }, ), ( "end_gateway", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([15, 10, 24]), }, + sign_material: None, }, ), ( "end_portal", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([15, 10, 24]), }, + sign_material: None, }, ), ( "end_portal_frame", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([91, 120, 97]), }, + sign_material: None, }, ), ( "end_rod", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "end_stone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([219, 222, 158]), }, + sign_material: None, }, ), ( "end_stone_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([218, 224, 162]), }, + sign_material: None, }, ), ( "end_stone_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([218, 224, 162]), }, + sign_material: None, }, ), ( "end_stone_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([218, 224, 162]), }, + sign_material: None, }, ), ( "end_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([218, 224, 162]), }, + sign_material: None, }, ), ( "ender_chest", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([15, 10, 24]), }, + sign_material: None, }, ), ( "exposed_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([161, 125, 103]), }, + sign_material: None, }, ), ( "exposed_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "exposed_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "exposed_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "farmland", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([81, 44, 15]), }, + sign_material: None, }, ), ( "fern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "fire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([211, 140, 53]), }, + sign_material: None, }, ), ( "fire_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "fire_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([163, 35, 46]), }, + sign_material: None, }, ), ( "fire_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "fire_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "fletching_table", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([197, 180, 133]), }, + sign_material: None, }, ), ( "flower_pot", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 68, 53]), }, + sign_material: None, }, ), ( "flowering_azalea", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 121, 64]), }, + sign_material: None, }, ), ( "flowering_azalea_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 111, 60]), }, + sign_material: None, }, ), ( "frogspawn", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([105, 90, 82]), }, + sign_material: None, }, ), ( "frosted_ice", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([140, 181, 252]), }, + sign_material: None, }, ), ( "furnace", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 109, 109]), }, + sign_material: None, }, ), ( "gilded_blackstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([55, 42, 38]), }, + sign_material: None, }, ), ( "glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([175, 213, 219]), }, + sign_material: None, }, ), ( "glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([170, 210, 217]), }, + sign_material: None, }, ), ( "glow_item_frame", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "glow_lichen", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "glowstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([171, 131, 84]), }, + sign_material: None, }, ), ( "gold_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([246, 208, 61]), }, + sign_material: None, }, ), ( "gold_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([145, 133, 106]), }, + sign_material: None, }, ), ( "granite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 103, 85]), }, + sign_material: None, }, ), ( "granite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 103, 85]), }, + sign_material: None, }, ), ( "granite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 103, 85]), }, + sign_material: None, }, ), ( "granite_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 103, 85]), }, + sign_material: None, }, ), ( "grass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "grass_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([147, 147, 147]), }, + sign_material: None, }, ), ( "grass_path", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([148, 121, 65]), }, + sign_material: None, }, ), ( "gravel", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 127, 126]), }, + sign_material: None, }, ), ( "gray_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "gray_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "gray_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "gray_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "gray_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([62, 68, 71]), }, + sign_material: None, }, ), ( "gray_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([54, 57, 61]), }, + sign_material: None, }, ), ( "gray_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([76, 81, 84]), }, + sign_material: None, }, ), ( "gray_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([83, 90, 93]), }, + sign_material: None, }, ), ( "gray_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([55, 58, 62]), }, + sign_material: None, }, ), ( "gray_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([76, 76, 76]), }, + sign_material: None, }, ), ( "gray_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 73, 73]), }, + sign_material: None, }, ), ( "gray_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([57, 42, 35]), }, + sign_material: None, }, ), ( "gray_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "gray_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([62, 68, 71]), }, + sign_material: None, }, ), ( "green_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "green_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "green_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "green_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "green_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([84, 109, 27]), }, + sign_material: None, }, ), ( "green_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 91, 36]), }, + sign_material: None, }, ), ( "green_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([97, 119, 44]), }, + sign_material: None, }, ), ( "green_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 142, 67]), }, + sign_material: None, }, ), ( "green_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 100, 31]), }, + sign_material: None, }, ), ( "green_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([102, 127, 51]), }, + sign_material: None, }, ), ( "green_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([97, 122, 48]), }, + sign_material: None, }, ), ( "green_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([76, 83, 42]), }, + sign_material: None, }, ), ( "green_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "green_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([84, 109, 27]), }, + sign_material: None, }, ), ( "grindstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 142, 142]), }, + sign_material: None, }, ), ( "hanging_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([161, 115, 91]), }, + sign_material: None, }, ), ( "hay_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([165, 139, 12]), }, + sign_material: None, }, ), ( "heavy_weighted_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([220, 220, 220]), }, + sign_material: None, }, ), ( "honey_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([251, 185, 52]), }, + sign_material: None, }, ), ( "honeycomb_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([229, 148, 29]), }, + sign_material: None, }, ), ( "hopper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([75, 74, 75]), }, + sign_material: None, }, ), ( "horn_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "horn_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([216, 199, 66]), }, + sign_material: None, }, ), ( "horn_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "horn_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "ice", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([145, 183, 253]), }, + sign_material: None, }, ), ( "infested_chiseled_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 118, 119]), }, + sign_material: None, }, ), ( "infested_cobblestone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 127, 127]), }, + sign_material: None, }, ), ( "infested_cracked_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([118, 117, 118]), }, + sign_material: None, }, ), ( "infested_deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 80, 82]), }, + sign_material: None, }, ), ( "infested_mossy_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 121, 105]), }, + sign_material: None, }, ), ( "infested_stone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "infested_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 121, 122]), }, + sign_material: None, }, ), ( "iron_bars", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 139, 135]), }, + sign_material: None, }, ), ( "iron_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([220, 220, 220]), }, + sign_material: None, }, ), ( "iron_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([194, 193, 193]), }, + sign_material: None, }, ), ( "iron_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([136, 129, 122]), }, + sign_material: None, }, ), ( "iron_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([202, 202, 202]), }, + sign_material: None, }, ), ( "item_frame", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "jack_o_lantern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([214, 152, 52]), }, + sign_material: None, }, ), ( "jigsaw", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 69, 81]), }, + sign_material: None, }, ), ( "jukebox", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 64, 47]), }, + sign_material: None, }, ), ( "jungle_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "jungle_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([163, 119, 84]), }, + sign_material: None, }, ), ( "jungle_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("jungle"), }, ), ( "jungle_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: Color([156, 154, 143]), }, + sign_material: None, }, ), ( "jungle_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 109, 70]), }, + sign_material: None, }, ), ( "jungle_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 81, 16]), }, + sign_material: None, }, ), ( "jungle_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: Some("jungle"), }, ), ( "jungle_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 115, 80]), }, + sign_material: None, }, ), ( "jungle_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([152, 110, 77]), }, + sign_material: None, }, ), ( "jungle_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("jungle"), }, ), ( "jungle_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("jungle"), }, ), ( "jungle_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([85, 67, 25]), }, + sign_material: None, }, ), ( "kelp", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "kelp_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([86, 130, 42]), }, + sign_material: None, }, ), ( "ladder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lantern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([106, 91, 83]), }, + sign_material: None, }, ), ( "lapis_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([30, 67, 140]), }, + sign_material: None, }, ), ( "lapis_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([107, 117, 141]), }, + sign_material: None, }, ), ( "large_amethyst_bud", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "large_fern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "lava", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([212, 90, 18]), }, + sign_material: None, }, ), ( "lava_cauldron", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 72, 74]), }, + sign_material: None, }, ), ( "lectern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([173, 137, 83]), }, + sign_material: None, }, ), ( "lever", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_blue_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_blue_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_blue_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_blue_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "light_blue_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([58, 175, 217]), }, + sign_material: None, }, ), ( "light_blue_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([35, 137, 198]), }, + sign_material: None, }, ), ( "light_blue_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([74, 180, 213]), }, + sign_material: None, }, ), ( "light_blue_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([94, 164, 208]), }, + sign_material: None, }, ), ( "light_blue_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([49, 163, 212]), }, + sign_material: None, }, ), ( "light_blue_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([102, 153, 216]), }, + sign_material: None, }, ), ( "light_blue_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([97, 147, 208]), }, + sign_material: None, }, ), ( "light_blue_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([113, 108, 137]), }, + sign_material: None, }, ), ( "light_blue_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_blue_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([58, 175, 217]), }, + sign_material: None, }, ), ( "light_gray_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_gray_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_gray_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_gray_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "light_gray_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 142, 134]), }, + sign_material: None, }, ), ( "light_gray_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 115]), }, + sign_material: None, }, ), ( "light_gray_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 154, 148]), }, + sign_material: None, }, ), ( "light_gray_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([144, 166, 167]), }, + sign_material: None, }, ), ( "light_gray_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 124, 115]), }, + sign_material: None, }, ), ( "light_gray_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([153, 153, 153]), }, + sign_material: None, }, ), ( "light_gray_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([147, 147, 147]), }, + sign_material: None, }, ), ( "light_gray_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([135, 106, 97]), }, + sign_material: None, }, ), ( "light_gray_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "light_gray_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 142, 134]), }, + sign_material: None, }, ), ( "light_weighted_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([246, 208, 61]), }, + sign_material: None, }, ), ( "lightning_rod", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lilac", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 125, 147]), }, + sign_material: None, }, ), ( "lily_of_the_valley", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lily_pad", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([133, 133, 133]), }, + sign_material: None, }, ), ( "lime_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lime_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lime_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lime_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "lime_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 185, 25]), }, + sign_material: None, }, ), ( "lime_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([94, 168, 24]), }, + sign_material: None, }, ), ( "lime_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 189, 41]), }, + sign_material: None, }, ), ( "lime_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 197, 55]), }, + sign_material: None, }, ), ( "lime_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 172, 23]), }, + sign_material: None, }, ), ( "lime_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 204, 25]), }, + sign_material: None, }, ), ( "lime_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 196, 24]), }, + sign_material: None, }, ), ( "lime_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 117, 52]), }, + sign_material: None, }, ), ( "lime_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "lime_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 185, 25]), }, + sign_material: None, }, ), ( "lodestone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([147, 149, 152]), }, + sign_material: None, }, ), ( "loom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 119, 91]), }, + sign_material: None, }, ), ( "magenta_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "magenta_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "magenta_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "magenta_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "magenta_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([189, 68, 179]), }, + sign_material: None, }, ), ( "magenta_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([169, 48, 159]), }, + sign_material: None, }, ), ( "magenta_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 83, 184]), }, + sign_material: None, }, ), ( "magenta_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([208, 100, 191]), }, + sign_material: None, }, ), ( "magenta_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([173, 54, 163]), }, + sign_material: None, }, ), ( "magenta_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([178, 76, 216]), }, + sign_material: None, }, ), ( "magenta_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([171, 73, 208]), }, + sign_material: None, }, ), ( "magenta_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([149, 88, 108]), }, + sign_material: None, }, ), ( "magenta_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "magenta_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([189, 68, 179]), }, + sign_material: None, }, ), ( "magma_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 63, 31]), }, + sign_material: None, }, ), ( "mangrove_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "mangrove_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 48, 46]), }, + sign_material: None, }, ), ( "mangrove_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("mangrove"), }, ), ( "mangrove_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: Color([129, 128, 128]), }, + sign_material: None, }, ), ( "mangrove_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([102, 48, 42]), }, + sign_material: None, }, ), ( "mangrove_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_propagule", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([96, 174, 83]), }, + sign_material: None, }, ), ( "mangrove_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([74, 59, 38]), }, + sign_material: None, }, ), ( "mangrove_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: Some("mangrove"), }, ), ( "mangrove_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 54, 48]), }, + sign_material: None, }, ), ( "mangrove_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 46, 42]), }, + sign_material: None, }, ), ( "mangrove_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("mangrove"), }, ), ( "mangrove_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("mangrove"), }, ), ( "mangrove_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([83, 66, 41]), }, + sign_material: None, }, ), ( "medium_amethyst_bud", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "melon", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([111, 144, 30]), }, + sign_material: None, }, ), ( "melon_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([153, 153, 153]), }, + sign_material: None, }, ), ( "moss_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([89, 109, 45]), }, + sign_material: None, }, ), ( "moss_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([89, 109, 45]), }, + sign_material: None, }, ), ( "mossy_cobblestone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 118, 94]), }, + sign_material: None, }, ), ( "mossy_cobblestone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 118, 94]), }, + sign_material: None, }, ), ( "mossy_cobblestone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 118, 94]), }, + sign_material: None, }, ), ( "mossy_cobblestone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([110, 118, 94]), }, + sign_material: None, }, ), ( "mossy_stone_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 121, 105]), }, + sign_material: None, }, ), ( "mossy_stone_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 121, 105]), }, + sign_material: None, }, ), ( "mossy_stone_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 121, 105]), }, + sign_material: None, }, ), ( "mossy_stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 121, 105]), }, + sign_material: None, }, ), ( "moving_piston", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "mud", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([60, 57, 60]), }, + sign_material: None, }, ), ( "mud_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 103, 79]), }, + sign_material: None, }, ), ( "mud_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 103, 79]), }, + sign_material: None, }, ), ( "mud_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 103, 79]), }, + sign_material: None, }, ), ( "mud_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 103, 79]), }, + sign_material: None, }, ), ( "muddy_mangrove_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([70, 58, 45]), }, + sign_material: None, }, ), ( "mushroom_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([203, 196, 185]), }, + sign_material: None, }, ), ( "mycelium", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([111, 98, 101]), }, + sign_material: None, }, ), ( "nether_brick_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 21, 26]), }, + sign_material: None, }, ), ( "nether_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 21, 26]), }, + sign_material: None, }, ), ( "nether_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 21, 26]), }, + sign_material: None, }, ), ( "nether_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 21, 26]), }, + sign_material: None, }, ), ( "nether_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 21, 26]), }, + sign_material: None, }, ), ( "nether_gold_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 54, 42]), }, + sign_material: None, }, ), ( "nether_portal", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([89, 11, 192]), }, + sign_material: None, }, ), ( "nether_quartz_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([117, 65, 62]), }, + sign_material: None, }, ), ( "nether_sprouts", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([19, 151, 133]), }, + sign_material: None, }, ), ( "nether_wart", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([111, 18, 19]), }, + sign_material: None, }, ), ( "nether_wart_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 2, 2]), }, + sign_material: None, }, ), ( "netherite_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([66, 61, 63]), }, + sign_material: None, }, ), ( "netherrack", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([97, 38, 38]), }, + sign_material: None, }, ), ( "note_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([88, 58, 40]), }, + sign_material: None, }, ), ( "oak_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "oak_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([140, 110, 66]), }, + sign_material: None, }, ), ( "oak_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("oak"), }, ), ( "oak_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: Color([144, 144, 144]), }, + sign_material: None, }, ), ( "oak_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([151, 121, 73]), }, + sign_material: None, }, ), ( "oak_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 106, 40]), }, + sign_material: None, }, ), ( "oak_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: Some("oak"), }, ), ( "oak_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "oak_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([124, 99, 56]), }, + sign_material: None, }, ), ( "oak_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("oak"), }, ), ( "oak_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("oak"), }, ), ( "oak_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 85, 50]), }, + sign_material: None, }, ), ( "observer", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([98, 98, 98]), }, + sign_material: None, }, ), ( "obsidian", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([15, 10, 24]), }, + sign_material: None, }, ), ( "ochre_froglight", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([250, 245, 206]), }, + sign_material: None, }, ), ( "orange_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "orange_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "orange_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "orange_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "orange_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([240, 118, 19]), }, + sign_material: None, }, ), ( "orange_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([224, 97, 0]), }, + sign_material: None, }, ), ( "orange_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([227, 131, 31]), }, + sign_material: None, }, ), ( "orange_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 147, 91]), }, + sign_material: None, }, ), ( "orange_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([234, 106, 8]), }, + sign_material: None, }, ), ( "orange_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([216, 127, 51]), }, + sign_material: None, }, ), ( "orange_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([208, 122, 48]), }, + sign_material: None, }, ), ( "orange_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([161, 83, 37]), }, + sign_material: None, }, ), ( "orange_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "orange_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "orange_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([240, 118, 19]), }, + sign_material: None, }, ), ( "oxeye_daisy", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "oxidized_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([82, 162, 132]), }, + sign_material: None, }, ), ( "oxidized_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "oxidized_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "oxidized_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "packed_ice", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([141, 180, 250]), }, + sign_material: None, }, ), ( "packed_mud", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 106, 79]), }, + sign_material: None, }, ), ( "pearlescent_froglight", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([245, 240, 239]), }, + sign_material: None, }, ), ( "peony", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([129, 126, 139]), }, + sign_material: None, }, ), ( "petrified_oak_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "piglin_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "piglin_wall_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "pink_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([237, 141, 172]), }, + sign_material: None, }, ), ( "pink_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([213, 101, 142]), }, + sign_material: None, }, ), ( "pink_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([228, 153, 181]), }, + sign_material: None, }, ), ( "pink_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 154, 181]), }, + sign_material: None, }, ), ( "pink_petals", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([230, 121, 157]), }, + sign_material: None, }, ), ( "pink_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([242, 127, 165]), }, + sign_material: None, }, ), ( "pink_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([233, 122, 159]), }, + sign_material: None, }, ), ( "pink_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([161, 78, 78]), }, + sign_material: None, }, ), ( "pink_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "pink_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([237, 141, 172]), }, + sign_material: None, }, ), ( "piston", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 104, 96]), }, + sign_material: None, }, ), ( "piston_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([153, 127, 85]), }, + sign_material: None, }, ), ( "pitcher_crop", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([193, 165, 103]), }, + sign_material: None, }, ), ( "pitcher_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 144, 189]), }, + sign_material: None, }, ), ( "player_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "player_wall_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "podzol", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([91, 63, 24]), }, + sign_material: None, }, ), ( "pointed_dripstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([129, 102, 89]), }, + sign_material: None, }, ), ( "polished_andesite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([132, 134, 133]), }, + sign_material: None, }, ), ( "polished_andesite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([132, 134, 133]), }, + sign_material: None, }, ), ( "polished_andesite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([132, 134, 133]), }, + sign_material: None, }, ), ( "polished_basalt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 98, 100]), }, + sign_material: None, }, ), ( "polished_blackstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "polished_blackstone_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([48, 42, 49]), }, + sign_material: None, }, ), ( "polished_blackstone_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([48, 42, 49]), }, + sign_material: None, }, ), ( "polished_blackstone_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([48, 42, 49]), }, + sign_material: None, }, ), ( "polished_blackstone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([48, 42, 49]), }, + sign_material: None, }, ), ( "polished_blackstone_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "polished_blackstone_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "polished_blackstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "polished_blackstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "polished_blackstone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 48, 56]), }, + sign_material: None, }, ), ( "polished_deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 73]), }, + sign_material: None, }, ), ( "polished_deepslate_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 73]), }, + sign_material: None, }, ), ( "polished_deepslate_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 73]), }, + sign_material: None, }, ), ( "polished_deepslate_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 73]), }, + sign_material: None, }, ), ( "polished_diorite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 193, 194]), }, + sign_material: None, }, ), ( "polished_diorite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 193, 194]), }, + sign_material: None, }, ), ( "polished_diorite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 193, 194]), }, + sign_material: None, }, ), ( "polished_granite", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 106, 89]), }, + sign_material: None, }, ), ( "polished_granite_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 106, 89]), }, + sign_material: None, }, ), ( "polished_granite_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 106, 89]), }, + sign_material: None, }, ), ( "poppy", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "potatoes", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([84, 135, 47]), }, + sign_material: None, }, ), ( "potted_acacia_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([118, 117, 23]), }, + sign_material: None, }, ), ( "potted_allium", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([158, 137, 183]), }, + sign_material: None, }, ), ( "potted_azalea_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([101, 124, 47]), }, + sign_material: None, }, ), ( "potted_azure_bluet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([169, 204, 127]), }, + sign_material: None, }, ), ( "potted_bamboo", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 144, 19]), }, + sign_material: None, }, ), ( "potted_birch_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 160, 79]), }, + sign_material: None, }, ), ( "potted_blue_orchid", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 162, 168]), }, + sign_material: None, }, ), ( "potted_brown_mushroom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([153, 116, 92]), }, + sign_material: None, }, ), ( "potted_cactus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([85, 127, 43]), }, + sign_material: None, }, ), ( "potted_cherry_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([164, 117, 143]), }, + sign_material: None, }, ), ( "potted_cornflower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 121, 146]), }, + sign_material: None, }, ), ( "potted_crimson_fungus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([141, 44, 29]), }, + sign_material: None, }, ), ( "potted_crimson_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 8, 41]), }, + sign_material: None, }, ), ( "potted_dandelion", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([147, 172, 43]), }, + sign_material: None, }, ), ( "potted_dark_oak_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([61, 90, 30]), }, + sign_material: None, }, ), ( "potted_dead_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([107, 78, 40]), }, + sign_material: None, }, ), ( "potted_fern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([124, 124, 124]), }, + sign_material: None, }, ), ( "potted_flowering_azalea_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([112, 121, 64]), }, + sign_material: None, }, ), ( "potted_jungle_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 81, 16]), }, + sign_material: None, }, ), ( "potted_lily_of_the_valley", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([123, 174, 95]), }, + sign_material: None, }, ), ( "potted_mangrove_propagule", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([96, 174, 83]), }, + sign_material: None, }, ), ( "potted_oak_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([77, 106, 40]), }, + sign_material: None, }, ), ( "potted_orange_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 142, 30]), }, + sign_material: None, }, ), ( "potted_oxeye_daisy", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([179, 202, 143]), }, + sign_material: None, }, ), ( "potted_pink_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 157, 78]), }, + sign_material: None, }, ), ( "potted_poppy", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([128, 64, 37]), }, + sign_material: None, }, ), ( "potted_red_mushroom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([216, 75, 67]), }, + sign_material: None, }, ), ( "potted_red_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([89, 128, 32]), }, + sign_material: None, }, ), ( "potted_spruce_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 60, 36]), }, + sign_material: None, }, ), ( "potted_torchflower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([100, 101, 77]), }, + sign_material: None, }, ), ( "potted_warped_fungus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([74, 109, 87]), }, + sign_material: None, }, ), ( "potted_warped_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 136, 123]), }, + sign_material: None, }, ), ( "potted_white_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([93, 164, 71]), }, + sign_material: None, }, ), ( "potted_wither_rose", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([41, 44, 23]), }, + sign_material: None, }, ), ( "powder_snow", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 253, 253]), }, + sign_material: None, }, ), ( "powder_snow_cauldron", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 72, 74]), }, + sign_material: None, }, ), ( "powered_rail", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 109, 74]), }, + sign_material: None, }, ), ( "prismarine", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 156, 151]), }, + sign_material: None, }, ), ( "prismarine_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 171, 158]), }, + sign_material: None, }, ), ( "prismarine_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 171, 158]), }, + sign_material: None, }, ), ( "prismarine_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 171, 158]), }, + sign_material: None, }, ), ( "prismarine_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 156, 151]), }, + sign_material: None, }, ), ( "prismarine_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 156, 151]), }, + sign_material: None, }, ), ( "prismarine_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([99, 156, 151]), }, + sign_material: None, }, ), ( "pumpkin", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([198, 118, 24]), }, + sign_material: None, }, ), ( "pumpkin_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([154, 154, 154]), }, + sign_material: None, }, ), ( "purple_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "purple_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "purple_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "purple_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "purple_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([121, 42, 172]), }, + sign_material: None, }, ), ( "purple_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([100, 31, 156]), }, + sign_material: None, }, ), ( "purple_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 55, 177]), }, + sign_material: None, }, ), ( "purple_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 47, 152]), }, + sign_material: None, }, ), ( "purple_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 32, 156]), }, + sign_material: None, }, ), ( "purple_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([127, 63, 178]), }, + sign_material: None, }, ), ( "purple_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 61, 171]), }, + sign_material: None, }, ), ( "purple_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([118, 70, 86]), }, + sign_material: None, }, ), ( "purple_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "purple_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([121, 42, 172]), }, + sign_material: None, }, ), ( "purpur_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([169, 125, 169]), }, + sign_material: None, }, ), ( "purpur_pillar", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([171, 129, 171]), }, + sign_material: None, }, ), ( "purpur_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([169, 125, 169]), }, + sign_material: None, }, ), ( "purpur_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([169, 125, 169]), }, + sign_material: None, }, ), ( "quartz_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "quartz_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([234, 229, 221]), }, + sign_material: None, }, ), ( "quartz_pillar", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 230, 224]), }, + sign_material: None, }, ), ( "quartz_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "quartz_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "rail", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 111, 88]), }, + sign_material: None, }, ), ( "raw_copper_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 105, 79]), }, + sign_material: None, }, ), ( "raw_gold_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([221, 169, 46]), }, + sign_material: None, }, ), ( "raw_iron_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([166, 135, 107]), }, + sign_material: None, }, ), ( "red_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "red_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 39, 34]), }, + sign_material: None, }, ), ( "red_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 32, 32]), }, + sign_material: None, }, ), ( "red_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([168, 54, 50]), }, + sign_material: None, }, ), ( "red_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 59, 53]), }, + sign_material: None, }, ), ( "red_mushroom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_mushroom_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([200, 46, 45]), }, + sign_material: None, }, ), ( "red_nether_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([69, 7, 9]), }, + sign_material: None, }, ), ( "red_nether_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([69, 7, 9]), }, + sign_material: None, }, ), ( "red_nether_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([69, 7, 9]), }, + sign_material: None, }, ), ( "red_nether_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([69, 7, 9]), }, + sign_material: None, }, ), ( "red_sand", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([190, 102, 33]), }, + sign_material: None, }, ), ( "red_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "red_sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "red_sandstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "red_sandstone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "red_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([140, 31, 30]), }, + sign_material: None, }, ), ( "red_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([153, 51, 51]), }, + sign_material: None, }, ), ( "red_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([147, 48, 48]), }, + sign_material: None, }, ), ( "red_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([143, 61, 46]), }, + sign_material: None, }, ), ( "red_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "red_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 39, 34]), }, + sign_material: None, }, ), ( "redstone_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([175, 24, 5]), }, + sign_material: None, }, ), ( "redstone_lamp", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([95, 54, 30]), }, + sign_material: None, }, ), ( "redstone_ore", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([140, 109, 109]), }, + sign_material: None, }, ), ( "redstone_torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "redstone_wall_torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "redstone_wire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([175, 24, 5]), }, + sign_material: None, }, ), ( "reinforced_deepslate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 82, 78]), }, + sign_material: None, }, ), ( "repeater", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 157, 156]), }, + sign_material: None, }, ), ( "repeating_command_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([129, 111, 176]), }, + sign_material: None, }, ), ( "respawn_anchor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([75, 26, 144]), }, + sign_material: None, }, ), ( "rooted_dirt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([144, 103, 76]), }, + sign_material: None, }, ), ( "rose_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([131, 66, 37]), }, + sign_material: None, }, ), ( "sand", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([219, 207, 163]), }, + sign_material: None, }, ), ( "sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "sandstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "sandstone_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "scaffolding", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([170, 131, 73]), }, + sign_material: None, }, ), ( "sculk", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([12, 29, 36]), }, + sign_material: None, }, ), ( "sculk_catalyst", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([15, 31, 38]), }, + sign_material: None, }, ), ( "sculk_sensor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([7, 70, 84]), }, + sign_material: None, }, ), ( "sculk_shrieker", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([198, 205, 169]), }, + sign_material: None, }, ), ( "sculk_vein", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([7, 48, 57]), }, + sign_material: None, }, ), ( "sea_lantern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([172, 199, 190]), }, + sign_material: None, }, ), ( "sea_pickle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([90, 97, 39]), }, + sign_material: None, }, ), ( "seagrass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "short_grass", - BlockType { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, }, ), ( "shroomlight", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([240, 146, 70]), }, + sign_material: None, }, ), ( "shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([139, 96, 139]), }, + sign_material: None, }, ), ( "sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: Some("oak"), }, ), ( "skeleton_skull", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "skeleton_wall_skull", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "slime_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([111, 192, 91]), }, + sign_material: None, }, ), ( "small_amethyst_bud", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "small_dripleaf", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "smithing_table", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([57, 58, 70]), }, + sign_material: None, }, ), ( "smoker", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([85, 83, 81]), }, + sign_material: None, }, ), ( "smooth_basalt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 72, 78]), }, + sign_material: None, }, ), ( "smooth_quartz", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "smooth_quartz_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "smooth_quartz_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([235, 229, 222]), }, + sign_material: None, }, ), ( "smooth_red_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "smooth_red_sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "smooth_red_sandstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([181, 97, 31]), }, + sign_material: None, }, ), ( "smooth_sandstone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "smooth_sandstone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "smooth_sandstone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([223, 214, 170]), }, + sign_material: None, }, ), ( "smooth_stone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([158, 158, 158]), }, + sign_material: None, }, ), ( "smooth_stone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([158, 158, 158]), }, + sign_material: None, }, ), ( "sniffer_egg", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([135, 105, 67]), }, + sign_material: None, }, ), ( "snow", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([249, 254, 254]), }, + sign_material: None, }, ), ( "snow_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([249, 254, 254]), }, + sign_material: None, }, ), ( "soul_campfire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([80, 204, 208]), }, + sign_material: None, }, ), ( "soul_fire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([51, 192, 197]), }, + sign_material: None, }, ), ( "soul_lantern", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([71, 99, 114]), }, + sign_material: None, }, ), ( "soul_sand", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([81, 62, 50]), }, + sign_material: None, }, ), ( "soul_soil", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([75, 57, 46]), }, + sign_material: None, }, ), ( "soul_torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "soul_wall_torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "spawner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([36, 46, 62]), }, + sign_material: None, }, ), ( "sponge", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([195, 192, 74]), }, + sign_material: None, }, ), ( "spore_blossom", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([206, 96, 158]), }, + sign_material: None, }, ), ( "spruce_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "spruce_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([106, 80, 48]), }, + sign_material: None, }, ), ( "spruce_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("spruce"), }, ), ( "spruce_leaves", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), color: Color([126, 126, 126]), }, + sign_material: None, }, ), ( "spruce_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([108, 80, 46]), }, + sign_material: None, }, ), ( "spruce_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_sapling", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 60, 36]), }, + sign_material: None, }, ), ( "spruce_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: Some("spruce"), }, ), ( "spruce_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([114, 84, 48]), }, + sign_material: None, }, ), ( "spruce_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([103, 79, 47]), }, + sign_material: None, }, ), ( "spruce_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("spruce"), }, ), ( "spruce_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("spruce"), }, ), ( "spruce_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([58, 37, 16]), }, + sign_material: None, }, ), ( "sticky_piston", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 104, 96]), }, + sign_material: None, }, ), ( "stone", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "stone_brick_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 121, 122]), }, + sign_material: None, }, ), ( "stone_brick_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 121, 122]), }, + sign_material: None, }, ), ( "stone_brick_wall", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 121, 122]), }, + sign_material: None, }, ), ( "stone_bricks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([122, 121, 122]), }, + sign_material: None, }, ), ( "stone_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "stone_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "stone_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "stone_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([125, 125, 125]), }, + sign_material: None, }, ), ( "stonecutter", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([123, 118, 111]), }, + sign_material: None, }, ), ( "stripped_acacia_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([166, 91, 51]), }, + sign_material: None, }, ), ( "stripped_acacia_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([174, 92, 59]), }, + sign_material: None, }, ), ( "stripped_bamboo_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([178, 158, 72]), }, + sign_material: None, }, ), ( "stripped_birch_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 171, 116]), }, + sign_material: None, }, ), ( "stripped_birch_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([196, 176, 118]), }, + sign_material: None, }, ), ( "stripped_cherry_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([221, 164, 157]), }, + sign_material: None, }, ), ( "stripped_cherry_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([215, 145, 148]), }, + sign_material: None, }, ), ( "stripped_crimson_hyphae", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([137, 57, 90]), }, + sign_material: None, }, ), ( "stripped_crimson_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([121, 56, 82]), }, + sign_material: None, }, ), ( "stripped_dark_oak_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([65, 44, 22]), }, + sign_material: None, }, ), ( "stripped_dark_oak_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([72, 56, 36]), }, + sign_material: None, }, ), ( "stripped_jungle_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([165, 122, 81]), }, + sign_material: None, }, ), ( "stripped_jungle_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([171, 132, 84]), }, + sign_material: None, }, ), ( "stripped_mangrove_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 43, 43]), }, + sign_material: None, }, ), ( "stripped_mangrove_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([119, 54, 47]), }, + sign_material: None, }, ), ( "stripped_oak_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([160, 129, 77]), }, + sign_material: None, }, ), ( "stripped_oak_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([177, 144, 86]), }, + sign_material: None, }, ), ( "stripped_spruce_log", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([105, 80, 46]), }, + sign_material: None, }, ), ( "stripped_spruce_wood", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([115, 89, 52]), }, + sign_material: None, }, ), ( "stripped_warped_hyphae", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([57, 150, 147]), }, + sign_material: None, }, ), ( "stripped_warped_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([52, 128, 124]), }, + sign_material: None, }, ), ( "structure_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([88, 74, 90]), }, + sign_material: None, }, ), ( "structure_void", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "sugar_cane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([148, 192, 101]), }, + sign_material: None, }, ), ( "sunflower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([246, 196, 54]), }, + sign_material: None, }, ), ( "suspicious_gravel", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([129, 125, 124]), }, + sign_material: None, }, ), ( "suspicious_sand", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([217, 204, 159]), }, + sign_material: None, }, ), ( "sweet_berry_bush", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([68, 77, 50]), }, + sign_material: None, }, ), ( "tall_grass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([151, 149, 151]), }, + sign_material: None, }, ), ( "tall_seagrass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([59, 139, 14]), }, + sign_material: None, }, ), ( "target", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([226, 170, 157]), }, + sign_material: None, }, ), ( "terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([152, 94, 67]), }, + sign_material: None, }, ), ( "tinted_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 38, 46]), }, + sign_material: None, }, ), ( "tnt", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([142, 62, 53]), }, + sign_material: None, }, ), ( "torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "torchflower", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "torchflower_crop", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "trapped_chest", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([162, 130, 78]), }, + sign_material: None, }, ), ( "tripwire", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "tripwire_hook", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "tube_coral", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "tube_coral_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([49, 87, 206]), }, + sign_material: None, }, ), ( "tube_coral_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "tube_coral_wall_fan", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "tuff", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([108, 109, 102]), }, + sign_material: None, }, ), ( "turtle_egg", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([228, 226, 191]), }, + sign_material: None, }, ), ( "twisting_vines", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 143, 124]), }, + sign_material: None, }, ), ( "twisting_vines_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 135, 122]), }, + sign_material: None, }, ), ( "verdant_froglight", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([229, 244, 228]), }, + sign_material: None, }, ), ( "vine", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: Color([116, 116, 116]), }, + sign_material: None, }, ), ( "void_air", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("oak"), }, ), ( "wall_torch", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "warped_button", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "warped_door", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([44, 126, 120]), }, + sign_material: None, }, ), ( "warped_fence", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_fence_gate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_fungus", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "warped_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("warped"), }, ), ( "warped_hyphae", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([58, 58, 77]), }, + sign_material: None, }, ), ( "warped_nylium", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 114, 101]), }, + sign_material: None, }, ), ( "warped_planks", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_pressure_plate", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_roots", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([20, 138, 124]), }, + sign_material: None, }, ), ( "warped_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: Some("warped"), }, ), ( "warped_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([43, 104, 99]), }, + sign_material: None, }, ), ( "warped_stem", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([53, 109, 110]), }, + sign_material: None, }, ), ( "warped_trapdoor", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([47, 119, 111]), }, + sign_material: None, }, ), ( "warped_wall_hanging_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("warped"), }, ), ( "warped_wall_sign", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: Some("warped"), }, ), ( "warped_wart_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([22, 119, 121]), }, + sign_material: None, }, ), ( "water", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: Color([177, 177, 177]), }, + sign_material: None, }, ), ( "water_cauldron", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([73, 72, 74]), }, + sign_material: None, }, ), ( "waxed_copper_block", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([192, 107, 79]), }, + sign_material: None, }, ), ( "waxed_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "waxed_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "waxed_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([191, 106, 80]), }, + sign_material: None, }, ), ( "waxed_exposed_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([161, 125, 103]), }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "waxed_exposed_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([154, 121, 101]), }, + sign_material: None, }, ), ( "waxed_oxidized_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([82, 162, 132]), }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "waxed_oxidized_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([79, 153, 126]), }, + sign_material: None, }, ), ( "waxed_weathered_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([108, 153, 110]), }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "waxed_weathered_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "weathered_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([108, 153, 110]), }, + sign_material: None, }, ), ( "weathered_cut_copper", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "weathered_cut_copper_slab", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "weathered_cut_copper_stairs", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([109, 145, 107]), }, + sign_material: None, }, ), ( "weeping_vines", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([104, 1, 0]), }, + sign_material: None, }, ), ( "weeping_vines_plant", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([132, 16, 12]), }, + sign_material: None, }, ), ( "wet_sponge", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([171, 181, 70]), }, + sign_material: None, }, ), ( "wheat", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([166, 151, 73]), }, + sign_material: None, }, ), ( "white_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "white_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "white_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "white_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "white_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([233, 236, 236]), }, + sign_material: None, }, ), ( "white_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([207, 213, 214]), }, + sign_material: None, }, ), ( "white_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([225, 227, 227]), }, + sign_material: None, }, ), ( "white_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([188, 212, 202]), }, + sign_material: None, }, ), ( "white_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([215, 220, 221]), }, + sign_material: None, }, ), ( "white_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([255, 255, 255]), }, + sign_material: None, }, ), ( "white_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([246, 246, 246]), }, + sign_material: None, }, ), ( "white_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([209, 178, 161]), }, + sign_material: None, }, ), ( "white_tulip", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "white_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "white_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([233, 236, 236]), }, + sign_material: None, }, ), ( "wither_rose", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "wither_skeleton_skull", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "wither_skeleton_wall_skull", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "yellow_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "yellow_bed", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "yellow_candle", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "yellow_candle_cake", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 222, 214]), }, + sign_material: None, }, ), ( "yellow_carpet", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 197, 39]), }, + sign_material: None, }, ), ( "yellow_concrete", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([240, 175, 21]), }, + sign_material: None, }, ), ( "yellow_concrete_powder", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([232, 199, 54]), }, + sign_material: None, }, ), ( "yellow_glazed_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([234, 192, 88]), }, + sign_material: None, }, ), ( "yellow_shulker_box", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 188, 29]), }, + sign_material: None, }, ), ( "yellow_stained_glass", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([229, 229, 51]), }, + sign_material: None, }, ), ( "yellow_stained_glass_pane", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([221, 221, 48]), }, + sign_material: None, }, ), ( "yellow_terracotta", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([186, 133, 35]), }, + sign_material: None, }, ), ( "yellow_wall_banner", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "yellow_wool", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), color: Color([248, 197, 39]), }, + sign_material: None, }, ), ( "zombie_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ( "zombie_wall_head", - BlockType { + ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{}), color: Color([0, 0, 0]), }, + sign_material: None, }, ), ]; diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index 676b92b..1175c88 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -57,11 +57,31 @@ impl BlockColor { } } +/// A block type specification (for use in constants) +#[derive(Debug, Clone)] +struct ConstBlockType { + /// Determines the rendered color of the block type + pub block_color: BlockColor, + /// Material of a sign block + pub sign_material: Option<&'static str>, +} + /// A block type specification #[derive(Debug, Clone)] pub struct BlockType { /// Determines the rendered color of the block type pub block_color: BlockColor, + /// Material of a sign block + pub sign_material: Option, +} + +impl From<&ConstBlockType> for BlockType { + fn from(value: &ConstBlockType) -> Self { + BlockType { + block_color: value.block_color, + sign_material: value.sign_material.map(String::from), + } + } } /// Used to look up standard Minecraft block types @@ -77,7 +97,7 @@ impl Default for BlockTypes { fn default() -> Self { let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES .iter() - .map(|(k, v)| (String::from(*k), v.clone())) + .map(|(k, v)| (String::from(*k), BlockType::from(v))) .collect(); let legacy_block_types = Box::new(legacy_block_types::LEGACY_BLOCK_TYPES.map(|inner| { inner.map(|id| { diff --git a/resource/blocks.json b/resource/blocks.json index 6f4f5e7..ce5c497 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -9,7 +9,10 @@ "acacia_fence_gate": { "texture": "acacia_planks" }, - "acacia_hanging_sign": null, + "acacia_hanging_sign": { + "sign_material": "acacia", + "texture": null + }, "acacia_leaves": { "foliage": true }, @@ -22,6 +25,7 @@ }, "acacia_sapling": {}, "acacia_sign": { + "sign_material": "acacia", "texture": "acacia_planks" }, "acacia_slab": { @@ -31,8 +35,14 @@ "texture": "acacia_planks" }, "acacia_trapdoor": {}, - "acacia_wall_hanging_sign": null, - "acacia_wall_sign": null, + "acacia_wall_hanging_sign": { + "sign_material": "acacia", + "texture": null + }, + "acacia_wall_sign": { + "sign_material": "acacia", + "texture": null + }, "acacia_wood": { "texture": "acacia_log" }, @@ -84,7 +94,10 @@ "bamboo_fence_gate": { "texture": "bamboo_planks" }, - "bamboo_hanging_sign": null, + "bamboo_hanging_sign": { + "sign_material": "bamboo", + "texture": null + }, "bamboo_mosaic": {}, "bamboo_mosaic_slab": { "texture": "bamboo_mosaic" @@ -98,6 +111,7 @@ }, "bamboo_sapling": null, "bamboo_sign": { + "sign_material": "bamboo", "texture": "bamboo_planks" }, "bamboo_slab": { @@ -107,8 +121,14 @@ "texture": "bamboo_planks" }, "bamboo_trapdoor": {}, - "bamboo_wall_hanging_sign": null, - "bamboo_wall_sign": null, + "bamboo_wall_hanging_sign": { + "sign_material": "bamboo", + "texture": null + }, + "bamboo_wall_sign": { + "sign_material": "bamboo", + "texture": null + }, "barrel": { "texture": "barrel_top" }, @@ -144,7 +164,10 @@ "birch_fence_gate": { "texture": "birch_planks" }, - "birch_hanging_sign": null, + "birch_hanging_sign": { + "sign_material": "birch", + "texture": null + }, "birch_leaves": { "birch": true }, @@ -157,6 +180,7 @@ }, "birch_sapling": {}, "birch_sign": { + "sign_material": "birch", "texture": "birch_planks" }, "birch_slab": { @@ -166,8 +190,14 @@ "texture": "birch_planks" }, "birch_trapdoor": {}, - "birch_wall_hanging_sign": null, - "birch_wall_sign": null, + "birch_wall_hanging_sign": { + "sign_material": "birch", + "texture": null + }, + "birch_wall_sign": { + "sign_material": "birch", + "texture": null + }, "birch_wood": { "texture": "birch_log" }, @@ -326,7 +356,10 @@ "cherry_fence_gate": { "texture": "cherry_planks" }, - "cherry_hanging_sign": null, + "cherry_hanging_sign": { + "sign_material": "cherry", + "texture": null + }, "cherry_leaves": {}, "cherry_log": { "texture": "cherry_log_top" @@ -337,6 +370,7 @@ }, "cherry_sapling": null, "cherry_sign": { + "sign_material": "cherry", "texture": "cherry_planks" }, "cherry_slab": { @@ -346,8 +380,14 @@ "texture": "cherry_planks" }, "cherry_trapdoor": {}, - "cherry_wall_hanging_sign": null, - "cherry_wall_sign": null, + "cherry_wall_hanging_sign": { + "sign_material": "cherry", + "texture": null + }, + "cherry_wall_sign": { + "sign_material": "cherry", + "texture": null + }, "cherry_wood": { "texture": "cherry_log" }, @@ -433,7 +473,10 @@ "texture": "crimson_planks" }, "crimson_fungus": null, - "crimson_hanging_sign": null, + "crimson_hanging_sign": { + "sign_material": "crimson", + "texture": null + }, "crimson_hyphae": { "texture": "crimson_stem" }, @@ -444,6 +487,7 @@ }, "crimson_roots": {}, "crimson_sign": { + "sign_material": "crimson", "texture": "crimson_planks" }, "crimson_slab": { @@ -456,8 +500,14 @@ "texture": "crimson_stem_top" }, "crimson_trapdoor": {}, - "crimson_wall_hanging_sign": null, - "crimson_wall_sign": null, + "crimson_wall_hanging_sign": { + "sign_material": "crimson", + "texture": null + }, + "crimson_wall_sign": { + "sign_material": "crimson", + "texture": null + }, "crying_obsidian": {}, "cut_copper": {}, "cut_copper_slab": { @@ -512,7 +562,10 @@ "dark_oak_fence_gate": { "texture": "dark_oak_planks" }, - "dark_oak_hanging_sign": null, + "dark_oak_hanging_sign": { + "sign_material": "dark_oak", + "texture": null + }, "dark_oak_leaves": { "foliage": true }, @@ -525,6 +578,7 @@ }, "dark_oak_sapling": {}, "dark_oak_sign": { + "sign_material": "dark_oak", "texture": "dark_oak_planks" }, "dark_oak_slab": { @@ -534,8 +588,14 @@ "texture": "dark_oak_planks" }, "dark_oak_trapdoor": {}, - "dark_oak_wall_hanging_sign": null, - "dark_oak_wall_sign": null, + "dark_oak_wall_hanging_sign": { + "sign_material": "dark_oak", + "texture": null + }, + "dark_oak_wall_sign": { + "sign_material": "dark_oak", + "texture": null + }, "dark_oak_wood": { "texture": "dark_oak_log" }, @@ -832,7 +892,10 @@ "jungle_fence_gate": { "texture": "jungle_planks" }, - "jungle_hanging_sign": null, + "jungle_hanging_sign": { + "sign_material": "jungle", + "texture": null + }, "jungle_leaves": { "foliage": true }, @@ -845,6 +908,7 @@ }, "jungle_sapling": {}, "jungle_sign": { + "sign_material": "jungle", "texture": "jungle_planks" }, "jungle_slab": { @@ -854,8 +918,14 @@ "texture": "jungle_planks" }, "jungle_trapdoor": {}, - "jungle_wall_hanging_sign": null, - "jungle_wall_sign": null, + "jungle_wall_hanging_sign": { + "sign_material": "jungle", + "texture": null + }, + "jungle_wall_sign": { + "sign_material": "jungle", + "texture": null + }, "jungle_wood": { "texture": "jungle_log" }, @@ -991,7 +1061,10 @@ "mangrove_fence_gate": { "texture": "mangrove_planks" }, - "mangrove_hanging_sign": null, + "mangrove_hanging_sign": { + "sign_material": "mangrove", + "texture": null + }, "mangrove_leaves": { "foliage": true }, @@ -1007,6 +1080,7 @@ "texture": "mangrove_roots_top" }, "mangrove_sign": { + "sign_material": "mangrove", "texture": "mangrove_planks" }, "mangrove_slab": { @@ -1016,8 +1090,14 @@ "texture": "mangrove_planks" }, "mangrove_trapdoor": {}, - "mangrove_wall_hanging_sign": null, - "mangrove_wall_sign": null, + "mangrove_wall_hanging_sign": { + "sign_material": "mangrove", + "texture": null + }, + "mangrove_wall_sign": { + "sign_material": "mangrove", + "texture": null + }, "mangrove_wood": { "texture": "mangrove_log" }, @@ -1105,7 +1185,10 @@ "oak_fence_gate": { "texture": "oak_planks" }, - "oak_hanging_sign": null, + "oak_hanging_sign": { + "sign_material": "oak", + "texture": null + }, "oak_leaves": { "foliage": true }, @@ -1118,6 +1201,7 @@ }, "oak_sapling": {}, "oak_sign": { + "sign_material": "oak", "texture": "oak_planks" }, "oak_slab": { @@ -1127,8 +1211,14 @@ "texture": "oak_planks" }, "oak_trapdoor": {}, - "oak_wall_hanging_sign": null, - "oak_wall_sign": null, + "oak_wall_hanging_sign": { + "sign_material": "oak", + "texture": null + }, + "oak_wall_sign": { + "sign_material": "oak", + "texture": null + }, "oak_wood": { "texture": "oak_log" }, @@ -1562,6 +1652,7 @@ "shroomlight": {}, "shulker_box": {}, "sign": { + "sign_material": "oak", "texture": "oak_planks" }, "skeleton_skull": null, @@ -1638,7 +1729,10 @@ "spruce_fence_gate": { "texture": "spruce_planks" }, - "spruce_hanging_sign": null, + "spruce_hanging_sign": { + "sign_material": "spruce", + "texture": null + }, "spruce_leaves": { "spruce": true }, @@ -1651,6 +1745,7 @@ }, "spruce_sapling": {}, "spruce_sign": { + "sign_material": "spruce", "texture": "spruce_planks" }, "spruce_slab": { @@ -1660,8 +1755,14 @@ "texture": "spruce_planks" }, "spruce_trapdoor": {}, - "spruce_wall_hanging_sign": null, - "spruce_wall_sign": null, + "spruce_wall_hanging_sign": { + "sign_material": "spruce", + "texture": null + }, + "spruce_wall_sign": { + "sign_material": "spruce", + "texture": null + }, "spruce_wood": { "texture": "spruce_log" }, @@ -1808,7 +1909,10 @@ "grass": true }, "void_air": null, - "wall_sign": null, + "wall_sign": { + "sign_material": "oak", + "texture": null + }, "wall_torch": null, "warped_button": null, "warped_door": { @@ -1821,7 +1925,10 @@ "texture": "warped_planks" }, "warped_fungus": null, - "warped_hanging_sign": null, + "warped_hanging_sign": { + "sign_material": "warped", + "texture": null + }, "warped_hyphae": { "texture": "warped_stem" }, @@ -1832,6 +1939,7 @@ }, "warped_roots": {}, "warped_sign": { + "sign_material": "warped", "texture": "warped_planks" }, "warped_slab": { @@ -1844,8 +1952,14 @@ "texture": "warped_stem_top" }, "warped_trapdoor": {}, - "warped_wall_hanging_sign": null, - "warped_wall_sign": null, + "warped_wall_hanging_sign": { + "sign_material": "warped", + "texture": null + }, + "warped_wall_sign": { + "sign_material": "warped", + "texture": null + }, "warped_wart_block": {}, "water": { "texture": "water_still", diff --git a/resource/extract.py b/resource/extract.py index 281f3a7..22a6c76 100755 --- a/resource/extract.py +++ b/resource/extract.py @@ -45,12 +45,17 @@ for name, info in blocks.items(): 'birch': False, 'spruce': False, 'water': False, + 'sign_material': None, } if info is None: continue - color = mean_color(info.get('texture', name)) + texture = info.get('texture', name) + + color = None + if texture: + color = mean_color(texture) if color: output[id]['color'] = color output[id]['opaque'] = True @@ -60,5 +65,7 @@ for name, info in blocks.items(): output[id]['spruce'] = info.get('spruce', False) output[id]['water'] = info.get('water', False) + output[id]['sign_material'] = info.get('sign_material') + with open(sys.argv[3], 'w') as f: json.dump(output, f) diff --git a/resource/generate.py b/resource/generate.py index 2e6cf21..da5cb94 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -18,7 +18,7 @@ with open(sys.argv[2], 'w') as f: print('', file=f) print('use super::*;', file=f) print('', file=f) - print('pub const BLOCK_TYPES: &[(&str, BlockType)] = &[', file=f) + print('pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[', file=f) for name, info in colors.items(): flags = [] @@ -36,13 +36,18 @@ with open(sys.argv[2], 'w') as f: flags.append('Water') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' - print('\t("%s", BlockType { ' % name, file=f) + sign_material = 'None' + if info['sign_material']: + sign_material = 'Some("%s")' % info['sign_material'] + + print('\t("%s", ConstBlockType { ' % name, file=f) print('\t\tblock_color: BlockColor { flags: %s, color: Color([%u, %u, %u]) },' % ( flags, info['color']['r'], info['color']['g'], info['color']['b'], ), file=f) + print('\t\tsign_material: %s,' % sign_material, file=f) print('}),', file=f) print('];', file=f) From 48a6e242ea5fdc6de8050bc3b96d018d1c387124 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Dec 2023 02:29:40 +0100 Subject: [PATCH 027/152] resource: add WallSign flag to block types Allow to distinguish wall signs from freestanding or -hanging signs. --- crates/resource/src/block_types.rs | 46 ++++++++++---------- crates/resource/src/lib.rs | 5 +++ resource/blocks.json | 69 ++++++++++++++++++++---------- resource/extract.py | 13 +++--- resource/generate.py | 2 + 5 files changed, 84 insertions(+), 51 deletions(-) diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index f9ec70d..7ee50af 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -147,7 +147,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "acacia_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("acacia"), @@ -157,7 +157,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "acacia_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("acacia"), @@ -507,7 +507,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "bamboo_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("bamboo"), @@ -517,7 +517,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "bamboo_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("bamboo"), @@ -777,7 +777,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "birch_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("birch"), @@ -787,7 +787,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "birch_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("birch"), @@ -1787,7 +1787,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "cherry_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("cherry"), @@ -1797,7 +1797,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "cherry_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("cherry"), @@ -2387,7 +2387,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "crimson_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("crimson"), @@ -2397,7 +2397,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "crimson_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("crimson"), @@ -2787,7 +2787,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "dark_oak_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("dark_oak"), @@ -2797,7 +2797,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "dark_oak_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("dark_oak"), @@ -4577,7 +4577,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "jungle_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("jungle"), @@ -4587,7 +4587,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "jungle_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("jungle"), @@ -5527,7 +5527,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "mangrove_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("mangrove"), @@ -5537,7 +5537,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "mangrove_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("mangrove"), @@ -6057,7 +6057,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "oak_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("oak"), @@ -6067,7 +6067,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "oak_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("oak"), @@ -8637,7 +8637,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "spruce_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("spruce"), @@ -8647,7 +8647,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "spruce_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("spruce"), @@ -9287,7 +9287,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("oak"), @@ -9467,7 +9467,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "warped_wall_hanging_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("warped"), @@ -9477,7 +9477,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "warped_wall_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), + flags: make_bitflags!(BlockFlag::{WallSign}), color: Color([0, 0, 0]), }, sign_material: Some("warped"), diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index 1175c88..1baffda 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -31,6 +31,11 @@ pub enum BlockFlag { Spruce, /// The block type is colored using biome water colors Water, + /// The block type is a wall sign + /// + /// The WallSign flag is used to distinguish wall signs from + /// freestanding or -hanging signs. + WallSign, } /// An RGB color with u8 components diff --git a/resource/blocks.json b/resource/blocks.json index ce5c497..ee052bd 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -37,11 +37,13 @@ "acacia_trapdoor": {}, "acacia_wall_hanging_sign": { "sign_material": "acacia", - "texture": null + "texture": null, + "wall_sign": true }, "acacia_wall_sign": { "sign_material": "acacia", - "texture": null + "texture": null, + "wall_sign": true }, "acacia_wood": { "texture": "acacia_log" @@ -123,11 +125,13 @@ "bamboo_trapdoor": {}, "bamboo_wall_hanging_sign": { "sign_material": "bamboo", - "texture": null + "texture": null, + "wall_sign": true }, "bamboo_wall_sign": { "sign_material": "bamboo", - "texture": null + "texture": null, + "wall_sign": true }, "barrel": { "texture": "barrel_top" @@ -192,11 +196,13 @@ "birch_trapdoor": {}, "birch_wall_hanging_sign": { "sign_material": "birch", - "texture": null + "texture": null, + "wall_sign": true }, "birch_wall_sign": { "sign_material": "birch", - "texture": null + "texture": null, + "wall_sign": true }, "birch_wood": { "texture": "birch_log" @@ -382,11 +388,13 @@ "cherry_trapdoor": {}, "cherry_wall_hanging_sign": { "sign_material": "cherry", - "texture": null + "texture": null, + "wall_sign": true }, "cherry_wall_sign": { "sign_material": "cherry", - "texture": null + "texture": null, + "wall_sign": true }, "cherry_wood": { "texture": "cherry_log" @@ -502,11 +510,13 @@ "crimson_trapdoor": {}, "crimson_wall_hanging_sign": { "sign_material": "crimson", - "texture": null + "texture": null, + "wall_sign": true }, "crimson_wall_sign": { "sign_material": "crimson", - "texture": null + "texture": null, + "wall_sign": true }, "crying_obsidian": {}, "cut_copper": {}, @@ -590,11 +600,13 @@ "dark_oak_trapdoor": {}, "dark_oak_wall_hanging_sign": { "sign_material": "dark_oak", - "texture": null + "texture": null, + "wall_sign": true }, "dark_oak_wall_sign": { "sign_material": "dark_oak", - "texture": null + "texture": null, + "wall_sign": true }, "dark_oak_wood": { "texture": "dark_oak_log" @@ -920,11 +932,13 @@ "jungle_trapdoor": {}, "jungle_wall_hanging_sign": { "sign_material": "jungle", - "texture": null + "texture": null, + "wall_sign": true }, "jungle_wall_sign": { "sign_material": "jungle", - "texture": null + "texture": null, + "wall_sign": true }, "jungle_wood": { "texture": "jungle_log" @@ -1092,11 +1106,13 @@ "mangrove_trapdoor": {}, "mangrove_wall_hanging_sign": { "sign_material": "mangrove", - "texture": null + "texture": null, + "wall_sign": true }, "mangrove_wall_sign": { "sign_material": "mangrove", - "texture": null + "texture": null, + "wall_sign": true }, "mangrove_wood": { "texture": "mangrove_log" @@ -1213,11 +1229,13 @@ "oak_trapdoor": {}, "oak_wall_hanging_sign": { "sign_material": "oak", - "texture": null + "texture": null, + "wall_sign": true }, "oak_wall_sign": { "sign_material": "oak", - "texture": null + "texture": null, + "wall_sign": true }, "oak_wood": { "texture": "oak_log" @@ -1757,11 +1775,13 @@ "spruce_trapdoor": {}, "spruce_wall_hanging_sign": { "sign_material": "spruce", - "texture": null + "texture": null, + "wall_sign": true }, "spruce_wall_sign": { "sign_material": "spruce", - "texture": null + "texture": null, + "wall_sign": true }, "spruce_wood": { "texture": "spruce_log" @@ -1911,7 +1931,8 @@ "void_air": null, "wall_sign": { "sign_material": "oak", - "texture": null + "texture": null, + "wall_sign": true }, "wall_torch": null, "warped_button": null, @@ -1954,11 +1975,13 @@ "warped_trapdoor": {}, "warped_wall_hanging_sign": { "sign_material": "warped", - "texture": null + "texture": null, + "wall_sign": true }, "warped_wall_sign": { "sign_material": "warped", - "texture": null + "texture": null, + "wall_sign": true }, "warped_wart_block": {}, "water": { diff --git a/resource/extract.py b/resource/extract.py index 22a6c76..9621b95 100755 --- a/resource/extract.py +++ b/resource/extract.py @@ -45,6 +45,7 @@ for name, info in blocks.items(): 'birch': False, 'spruce': False, 'water': False, + 'wall_sign': False, 'sign_material': None, } @@ -59,11 +60,13 @@ for name, info in blocks.items(): if color: output[id]['color'] = color output[id]['opaque'] = True - output[id]['grass'] = info.get('grass', False) - output[id]['foliage'] = info.get('foliage', False) - output[id]['birch'] = info.get('birch', False) - output[id]['spruce'] = info.get('spruce', False) - output[id]['water'] = info.get('water', False) + + output[id]['grass'] = info.get('grass', False) + output[id]['foliage'] = info.get('foliage', False) + output[id]['birch'] = info.get('birch', False) + output[id]['spruce'] = info.get('spruce', False) + output[id]['water'] = info.get('water', False) + output[id]['wall_sign'] = info.get('wall_sign', False) output[id]['sign_material'] = info.get('sign_material') diff --git a/resource/generate.py b/resource/generate.py index da5cb94..8064482 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -34,6 +34,8 @@ with open(sys.argv[2], 'w') as f: flags.append('Spruce') if info['water']: flags.append('Water') + if info['wall_sign']: + flags.append('WallSign') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' sign_material = 'None' From 9aacd9cc2b787495f4f54b39afe130d1e821b259 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 Jan 2024 22:06:23 +0100 Subject: [PATCH 028/152] resource: make regular signs transparent For consistency with other sign types. Signs will be shown on a separate layer. --- crates/resource/src/block_types.rs | 48 +++++++++++++++--------------- resource/blocks.json | 24 +++++++-------- src/core/common.rs | 4 +-- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 7ee50af..6229016 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -107,8 +107,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "acacia_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([168, 90, 50]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("acacia"), }, @@ -467,8 +467,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "bamboo_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([193, 173, 80]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("bamboo"), }, @@ -737,8 +737,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "birch_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([192, 175, 121]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("birch"), }, @@ -1747,8 +1747,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "cherry_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([226, 178, 172]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("cherry"), }, @@ -2337,8 +2337,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "crimson_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([101, 48, 70]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("crimson"), }, @@ -2747,8 +2747,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "dark_oak_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([66, 43, 20]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("dark_oak"), }, @@ -4537,8 +4537,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "jungle_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([160, 115, 80]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("jungle"), }, @@ -5487,8 +5487,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "mangrove_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([117, 54, 48]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("mangrove"), }, @@ -6017,8 +6017,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "oak_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("oak"), }, @@ -8167,8 +8167,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([162, 130, 78]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("oak"), }, @@ -8597,8 +8597,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "spruce_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([114, 84, 48]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("spruce"), }, @@ -9417,8 +9417,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "warped_sign", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([43, 104, 99]), + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), }, sign_material: Some("warped"), }, diff --git a/resource/blocks.json b/resource/blocks.json index ee052bd..f8b0165 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -26,7 +26,7 @@ "acacia_sapling": {}, "acacia_sign": { "sign_material": "acacia", - "texture": "acacia_planks" + "texture": null }, "acacia_slab": { "texture": "acacia_planks" @@ -114,7 +114,7 @@ "bamboo_sapling": null, "bamboo_sign": { "sign_material": "bamboo", - "texture": "bamboo_planks" + "texture": null }, "bamboo_slab": { "texture": "bamboo_planks" @@ -185,7 +185,7 @@ "birch_sapling": {}, "birch_sign": { "sign_material": "birch", - "texture": "birch_planks" + "texture": null }, "birch_slab": { "texture": "birch_planks" @@ -377,7 +377,7 @@ "cherry_sapling": null, "cherry_sign": { "sign_material": "cherry", - "texture": "cherry_planks" + "texture": null }, "cherry_slab": { "texture": "cherry_planks" @@ -496,7 +496,7 @@ "crimson_roots": {}, "crimson_sign": { "sign_material": "crimson", - "texture": "crimson_planks" + "texture": null }, "crimson_slab": { "texture": "crimson_planks" @@ -589,7 +589,7 @@ "dark_oak_sapling": {}, "dark_oak_sign": { "sign_material": "dark_oak", - "texture": "dark_oak_planks" + "texture": null }, "dark_oak_slab": { "texture": "dark_oak_planks" @@ -921,7 +921,7 @@ "jungle_sapling": {}, "jungle_sign": { "sign_material": "jungle", - "texture": "jungle_planks" + "texture": null }, "jungle_slab": { "texture": "jungle_planks" @@ -1095,7 +1095,7 @@ }, "mangrove_sign": { "sign_material": "mangrove", - "texture": "mangrove_planks" + "texture": null }, "mangrove_slab": { "texture": "mangrove_planks" @@ -1218,7 +1218,7 @@ "oak_sapling": {}, "oak_sign": { "sign_material": "oak", - "texture": "oak_planks" + "texture": null }, "oak_slab": { "texture": "oak_planks" @@ -1671,7 +1671,7 @@ "shulker_box": {}, "sign": { "sign_material": "oak", - "texture": "oak_planks" + "texture": null }, "skeleton_skull": null, "skeleton_wall_skull": null, @@ -1764,7 +1764,7 @@ "spruce_sapling": {}, "spruce_sign": { "sign_material": "spruce", - "texture": "spruce_planks" + "texture": null }, "spruce_slab": { "texture": "spruce_planks" @@ -1961,7 +1961,7 @@ "warped_roots": {}, "warped_sign": { "sign_material": "warped", - "texture": "warped_planks" + "texture": null }, "warped_slab": { "texture": "warped_planks" diff --git a/src/core/common.rs b/src/core/common.rs index d961ea9..ca6f424 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -22,7 +22,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); /// MinedMap map tile data version number /// @@ -34,7 +34,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); /// MinedMap mipmap data version number /// From fb361145eb4896aa83b457b3665d41999dcfb765 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Dec 2023 03:33:33 +0100 Subject: [PATCH 029/152] world: add sign position and material information to block entities --- src/core/region_processor.rs | 7 ++++- src/world/block_entity.rs | 36 ++++++++++++++++------- src/world/chunk.rs | 57 ++++++++++++++++++++++++++++++++---- 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index cff87b7..63d5c09 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -243,7 +243,12 @@ impl<'a> SingleRegionProcessor<'a> { } if self.entities_needed { - let mut block_entities = chunk.block_entities(); + let mut block_entities = chunk.block_entities().with_context(|| { + format!( + "Failed to process block entities for chunk {:?}", + chunk_coords, + ) + })?; self.entities.block_entities.append(&mut block_entities); } diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs index 9e60a23..182ad50 100644 --- a/src/world/block_entity.rs +++ b/src/world/block_entity.rs @@ -1,5 +1,6 @@ //! Processing of block entity data +use minedmap_resource::{BlockFlag, BlockType}; use serde::{Deserialize, Serialize}; use super::{ @@ -11,10 +12,14 @@ use super::{ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum SignKind { - /// Standing or attached sign + /// Standing sign Sign, + /// Sign attached to wall + WallSign, /// Hanging sign HangingSign, + /// Hanging sign attached to wall + HangingWallSign, } /// Processed sign data @@ -22,6 +27,9 @@ pub enum SignKind { pub struct Sign { /// The kind of the sign pub kind: SignKind, + /// The material of the sign + #[serde(skip_serializing_if = "Option::is_none", default)] + pub material: Option, /// The sign's front text #[serde(skip_serializing_if = "SignText::is_empty", default)] pub front_text: SignText, @@ -32,12 +40,13 @@ pub struct Sign { impl Sign { /// Processes a [de::BlockEntitySign] into a [Sign] - fn new(sign: &de::BlockEntitySign, kind: SignKind) -> Sign { + fn new(sign: &de::BlockEntitySign, kind: SignKind, material: Option) -> Sign { let (front_text, back_text) = sign.text(); let front_text = front_text.decode(); let back_text = back_text.decode(); Sign { kind, + material, front_text, back_text, } @@ -68,16 +77,21 @@ pub struct BlockEntity { impl BlockEntity { /// Processes a [de::BlockEntity] into a [BlockEntity] - pub fn new(entity: &de::BlockEntity) -> Option { - 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, + pub fn new(entity: &de::BlockEntity, block_type: Option<&BlockType>) -> Option { + let wall_sign = block_type + .map(|block_type| block_type.block_color.is(BlockFlag::WallSign)) + .unwrap_or_default(); + let (kind, sign) = match (&entity.data, wall_sign) { + (de::BlockEntityData::Sign(sign), false) => (SignKind::Sign, sign), + (de::BlockEntityData::Sign(sign), true) => (SignKind::WallSign, sign), + (de::BlockEntityData::HangingSign(sign), false) => (SignKind::HangingSign, sign), + (de::BlockEntityData::HangingSign(sign), true) => (SignKind::HangingWallSign, sign), + (de::BlockEntityData::Other, _) => return None, }; + let material = block_type + .as_ref() + .and_then(|block_type| block_type.sign_material.as_ref()); + let data = BlockEntityData::Sign(Sign::new(sign, kind, material.cloned())); Some(BlockEntity { x: entity.x, diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 5a8937e..bf1d78b 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -12,8 +12,9 @@ use anyhow::{bail, Context, Result}; use super::{block_entity::BlockEntity, de, section::*}; use crate::{ - resource::{BiomeTypes, BlockTypes}, + resource::{BiomeTypes, BlockType, BlockTypes}, types::*, + util::{self, ShiftMask}, }; /// Version-specific part of [Chunk] @@ -243,12 +244,58 @@ impl<'a> Chunk<'a> { } } + /// Returns the section at a [SectionY] coordinate + fn section_at(&self, y: SectionY) -> Option<&dyn Section> { + match &self.inner { + ChunkInner::V1_18 { section_map } => section_map + .get(&y) + .map(|(section, _, _)| -> &dyn Section { section }), + ChunkInner::V1_13 { section_map, .. } => section_map + .get(&y) + .map(|(section, _)| -> &dyn Section { section }), + ChunkInner::V0 { section_map, .. } => section_map + .get(&y) + .map(|(section, _)| -> &dyn Section { section }), + ChunkInner::Empty => None, + } + } + + /// Returns the [BlockType] at a given coordinate + fn block_type_at(&self, y: SectionY, coords: SectionBlockCoords) -> Result> { + let Some(section) = self.section_at(y) else { + return Ok(None); + }; + section.block_at(coords) + } + + /// Returns the [BlockType] at the coordinates of a [de::BlockEntity] + fn block_type_at_block_entity( + &self, + block_entity: &de::BlockEntity, + ) -> Result> { + let x: BlockX = util::from_flat_coord(block_entity.x).2; + let z: BlockZ = util::from_flat_coord(block_entity.z).2; + let (section_y, block_y) = block_entity.y.shift_mask(BLOCK_BITS); + + let coords = SectionBlockCoords { + xz: LayerBlockCoords { x, z }, + y: BlockY::new(block_y), + }; + + self.block_type_at(SectionY(section_y), coords) + } + /// Processes all of the chunk's block entities - pub fn block_entities(&self) -> Vec { - self.block_entities + pub fn block_entities(&self) -> Result> { + let entities: Vec> = self + .block_entities .iter() - .filter_map(BlockEntity::new) - .collect() + .map(|block_entity| { + let block_type = self.block_type_at_block_entity(block_entity)?; + Ok(BlockEntity::new(block_entity, block_type)) + }) + .collect::>()?; + Ok(entities.into_iter().flatten().collect()) } } From 6da921cca3aceecd9d891cd472d4c2f165dc8a5e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 Jan 2024 12:36:27 +0100 Subject: [PATCH 030/152] core: wrap long help texts --- Cargo.lock | 63 +++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 2 +- src/core/mod.rs | 6 ++++- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab7a97a..7c96fdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -125,6 +125,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bytemuck" version = "1.14.0" @@ -179,6 +185,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -287,6 +294,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "fastnbt" version = "2.4.4" @@ -481,6 +498,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "lock_api" version = "0.4.11" @@ -698,7 +721,7 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -749,7 +772,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -764,6 +787,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "ryu" version = "1.0.16" @@ -863,6 +899,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -987,6 +1033,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index f1b3094..28359f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ pre-release-replacements = [ [dependencies] anyhow = "1.0.68" bincode = "1.3.3" -clap = { version = "4.1.4", features = ["derive"] } +clap = { version = "4.1.4", features = ["derive", "wrap_help"] } fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" diff --git a/src/core/mod.rs b/src/core/mod.rs index 61bdb76..1afdf91 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -32,7 +32,11 @@ const VERSION: &str = git_version!( /// Command line arguments for minedmap CLI #[derive(Debug, Parser)] -#[command(about, version = VERSION.strip_prefix("v").unwrap())] +#[command( + about, + version = VERSION.strip_prefix("v").unwrap(), + max_term_width = 100, +)] pub struct Args { /// Number of parallel threads to use for processing /// From 9fd5689ebb1dab17398fb8866b337165cd0acdef Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 Jan 2024 14:21:12 +0100 Subject: [PATCH 031/152] core: add sign pattern command line argument handling --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/core/common.rs | 25 ++++++++++++++++++++++--- src/core/mod.rs | 14 +++++++++++++- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c96fdc..e50f306 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -554,6 +563,7 @@ dependencies = [ "num-integer", "num_cpus", "rayon", + "regex", "rustc-hash", "serde", "serde_json", @@ -775,6 +785,35 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/Cargo.toml b/Cargo.toml index 28359f3..5442162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" +regex = "1.10.2" rustc-hash = "1.1.0" serde = { version = "1.0.152", features = ["rc", "derive"] } serde_json = "1.0.99" diff --git a/src/core/common.rs b/src/core/common.rs index ca6f424..92d0019 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -6,7 +6,9 @@ use std::{ path::{Path, PathBuf}, }; +use anyhow::{Context, Result}; use indexmap::IndexSet; +use regex::RegexSet; use serde::{Deserialize, Serialize}; use crate::{ @@ -147,11 +149,13 @@ pub struct Config { pub viewer_info_path: PathBuf, /// Path of viewer entities file pub viewer_entities_path: PathBuf, + /// Sign text filter patterns + pub sign_patterns: RegexSet, } impl Config { /// Crates a new [Config] from [command line arguments](super::Args) - pub fn new(args: &super::Args) -> Self { + pub fn new(args: &super::Args) -> Result { let num_threads = match args.jobs { Some(0) => num_cpus::get(), Some(threads) => threads, @@ -168,7 +172,9 @@ impl Config { .iter() .collect(); - Config { + let sign_patterns = Self::sign_patterns(args).context("Failed to parse sign patterns")?; + + Ok(Config { num_threads, region_dir, level_dat_path, @@ -178,7 +184,20 @@ impl Config { entities_path_final, viewer_info_path, viewer_entities_path, - } + sign_patterns, + }) + } + + /// Parses the sign prefixes and sign filters into a [RegexSet] + fn sign_patterns(args: &super::Args) -> Result { + let prefix_patterns: Vec<_> = args + .sign_prefix + .iter() + .map(|prefix| format!("^{}", regex::escape(prefix))) + .collect(); + Ok(RegexSet::new( + prefix_patterns.iter().chain(args.sign_filter.iter()), + )?) } /// Constructs the path to an input region file diff --git a/src/core/mod.rs b/src/core/mod.rs index 1afdf91..274bae8 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -47,6 +47,18 @@ pub struct Args { /// Enable verbose messages #[arg(short, long)] pub verbose: bool, + /// Prefix for text of signs to show on the map + #[arg(long)] + pub sign_prefix: Vec, + /// Regular expression for text of signs to show on the map + /// + /// --sign-prefix and --sign-filter allow to filter for signs to display; + /// by default, none are visible. The options may be passed multiple times, + /// and a sign will be visible if it matches any pattern. + /// + /// To make all signs visible, pass an empty string to either option. + #[arg(long)] + pub sign_filter: Vec, /// Minecraft save directory pub input_dir: PathBuf, /// MinedMap data directory @@ -64,7 +76,7 @@ fn setup_threads(num_threads: usize) -> Result<()> { /// MinedMap CLI main function pub fn cli() -> Result<()> { let args = Args::parse(); - let config = Config::new(&args); + let config = Config::new(&args)?; tracing_subscriber::fmt() .with_max_level(if args.verbose { From a1dd77c8fdd5b5d13bc20c60a66bda4591c5cd6a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 Jan 2024 03:03:53 +0100 Subject: [PATCH 032/152] world/sign: implement Display for SignText --- src/world/json_text.rs | 18 +++++++++++++++++- src/world/sign.rs | 43 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/world/json_text.rs b/src/world/json_text.rs index 0f72dcc..a153179 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -1,6 +1,6 @@ //! Newtype and helper methods for handling Minecraft Raw JSON Text -use std::{collections::VecDeque, sync::Arc}; +use std::{collections::VecDeque, fmt::Display, sync::Arc}; use serde::{Deserialize, Serialize}; @@ -51,6 +51,12 @@ impl FormattedText { } } +impl Display for FormattedText { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.text.fmt(f) + } +} + /// A tree of [FormattedText] nodes /// /// Each node including the root has a `text` and a list of children (`extra`). @@ -87,6 +93,16 @@ impl FormattedTextList { } } +impl Display for FormattedTextList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for text in &self.0 { + text.fmt(f)?; + } + + Ok(()) + } +} + /// Raw deserialized [JSONText] /// /// A [JSONText] can contain various different JSON types. diff --git a/src/world/sign.rs b/src/world/sign.rs index 43cac47..616f7fa 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -1,6 +1,6 @@ //! Processing of sign text -use std::sync::Arc; +use std::{fmt::Display, sync::Arc}; use serde::{Deserialize, Serialize}; @@ -89,3 +89,44 @@ impl SignText { self.0.iter().all(|line| line.is_empty()) } } + +impl Display for SignText { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut iter = self.0.iter(); + + let Some(first) = iter.next() else { + return Ok(()); + }; + first.fmt(f)?; + + for text in iter { + f.write_str("\n")?; + text.fmt(f)?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn formatted_text(text: &str) -> FormattedText { + FormattedText { + text: text.to_string(), + ..Default::default() + } + } + + #[test] + fn test_sign_text_display() { + let sign_text = SignText(vec![ + FormattedTextList(vec![formatted_text("a"), formatted_text("b")]), + FormattedTextList(vec![formatted_text("c")]), + FormattedTextList(vec![formatted_text("d")]), + FormattedTextList(vec![formatted_text("e")]), + ]); + assert_eq!("ab\nc\nd\ne", sign_text.to_string()); + } +} From 87d4371922d0e1b287e253ad73d0dc8521559688 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 Jan 2024 03:27:08 +0100 Subject: [PATCH 033/152] core/metadata_writer: implement filtering for signs --- src/core/metadata_writer.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index caf7726..03aac70 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -6,7 +6,10 @@ use serde::Serialize; use crate::{ core::common::*, io::{fs, storage}, - world::{block_entity::BlockEntity, de}, + world::{ + block_entity::{self, BlockEntity, BlockEntityData}, + de, + }, }; /// Minimum and maximum X and Z tile coordinates for a mipmap level @@ -120,6 +123,19 @@ impl<'a> MetadataWriter<'a> { } } + /// Filter signs according to the sign pattern configuration + fn sign_filter(&self, sign: &block_entity::Sign) -> bool { + let front_text = sign.front_text.to_string(); + if self.config.sign_patterns.is_match(front_text.trim()) { + return true; + } + let back_text = sign.back_text.to_string(); + if self.config.sign_patterns.is_match(back_text.trim()) { + return true; + } + false + } + /// Generates [Entities] data from collected entity lists fn entities(&self) -> Result { let data: ProcessedEntities = @@ -127,7 +143,13 @@ impl<'a> MetadataWriter<'a> { .context("Failed to read entity data file")?; let ret = Entities { - signs: data.block_entities, + signs: data + .block_entities + .into_iter() + .filter(|entity| match &entity.data { + BlockEntityData::Sign(sign) => self.sign_filter(sign), + }) + .collect(), }; Ok(ret) From dca9c394f2493a902474ad437e42d96155d3bbb9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Nov 2023 16:20:16 +0100 Subject: [PATCH 034/152] viewer: display markers for signs Still needs better styling. It might also be nice to include the currently opened marker in the URL. --- viewer/MinedMap.js | 122 ++++++++++++++++++++++++++++++++++++++++++++- viewer/index.html | 4 ++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 1288dc9..0e9abe0 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -98,6 +98,106 @@ const parseHash = function () { return args; } +const colors = { + black: '#000000', + dark_blue: '#0000AA', + dark_green: '#00AA00', + dark_aqua: '#00AAAA', + dark_red: '#AA0000', + dark_purple: '#AA00AA', + gold: '#FFAA00', + gray: '#AAAAAA', + dark_gray: '#555555', + blue: '#5555FF', + green: '#55FF55', + aqua: '#55FFFF', + red: '#FF5555', + light_purple: '#FF55FF', + yellow: '#FFFF55', + white: '#FFFFFF', +}; + +function formatSignLine(line) { + const el = document.createElement('span'); + el.style.whiteSpace = 'pre'; + el.style.fontFamily = 'sans'; + + for (const span of line) { + const child = document.createElement('span'); + child.textContent = span.text; + + const color = colors[span.color ?? 'black'] || colors['black']; + + if (span.bold) + child.style.fontWeight = 'bold'; + if (span.italic) + child.style.fontStyle = 'italic'; + + child.style.textDecoration = ''; + if (span.underlined) + child.style.textDecoration += ' underline'; + if (span.strikethrough) + child.style.textDecoration += ' line-through'; + + child.style.color = color; + if (span.obfuscated) { + child.style.backgroundColor = color; + child.className = 'obfuscated'; + } + + el.appendChild(child); + } + return el; +} + +function loadSigns(signLayer) { + const xhr = new XMLHttpRequest(); + xhr.onload = function () { + const res = JSON.parse(this.responseText); + const groups = {}; + + // Group signs by x,z coordinates + for (const sign of res.signs) { + const key = `${sign.x},${sign.z}`; + const group = groups[key] ??= []; + group[sign.y] = sign; + } + + for (const [key, group] of Object.entries(groups)) { + const el = document.createElement('span'); + const [x, z] = key.split(',').map((i) => +i); + + group.forEach((sign) => { + if (sign.front_text) { + for (const line of sign.front_text) { + el.appendChild(formatSignLine(line)); + el.appendChild(document.createElement('br')); + } + + el.appendChild(document.createElement('hr')); + } + + if (sign.back_text) { + for (let line of sign.back_text) { + el.appendChild(formatSignLine(line)); + el.appendChild(document.createElement('br')); + } + + el.appendChild(document.createElement('hr')); + } + }); + + const lastChild = el.lastChild; + if (lastChild) + lastChild.remove(); + + L.marker([-z-0.5, x+0.5]).addTo(signLayer).bindPopup(el); + } + } + + xhr.open('GET', 'data/entities.json', true); + xhr.send(); +} window.createMap = function () { const xhr = new XMLHttpRequest(); @@ -106,7 +206,7 @@ window.createMap = function () { mipmaps = res.mipmaps, spawn = res.spawn; - let x, z, zoom, light; + let x, z, zoom, light, signs; const updateParams = function () { const args = parseHash(); @@ -115,6 +215,7 @@ window.createMap = function () { x = parseFloat(args['x']); z = parseFloat(args['z']); light = parseInt(args['light']); + signs = parseInt(args['signs'] ?? '1'); if (isNaN(zoom)) zoom = 0; @@ -140,14 +241,20 @@ window.createMap = function () { const mapLayer = new MinedMapLayer(mipmaps, 'map'); const lightLayer = new MinedMapLayer(mipmaps, 'light'); + const signLayer = L.layerGroup(); + + loadSigns(signLayer); mapLayer.addTo(map); if (light) map.addLayer(lightLayer); + if (signs) + map.addLayer(signLayer); const overlayMaps = { "Illumination": lightLayer, + "Signs": signLayer, }; L.control.layers({}, overlayMaps).addTo(map); @@ -167,6 +274,8 @@ window.createMap = function () { if (map.hasLayer(lightLayer)) ret += '&light=1'; + if (!map.hasLayer(signLayer)) + ret += '&signs=0'; return ret; }; @@ -175,7 +284,12 @@ window.createMap = function () { window.location.hash = makeHash(); }; - const refreshHash = function () { + const refreshHash = function (ev) { + if (ev.type === 'layeradd' || ev.type === 'layerremove') { + if (ev.layer !== lightLayer && ev.layer !== signLayer) + return; + } + zoom = map.getZoom(); center = map.getCenter(); x = Math.round(center.lng); @@ -203,6 +317,10 @@ window.createMap = function () { map.addLayer(lightLayer); else map.removeLayer(lightLayer); + if (signs) + map.addLayer(signLayer); + else + map.removeLayer(signLayer); updateHash(); }; diff --git a/viewer/index.html b/viewer/index.html index df57cb6..8327600 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -30,6 +30,10 @@ image-rendering: pixelated; -ms-interpolation-mode: nearest-neighbor; } + + span.obfuscated:hover { + background-color: transparent !important; + } From 7834315dd339555f6d5a5aa3e24e4ceba0802689 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 Jan 2024 22:59:37 +0100 Subject: [PATCH 035/152] viewer: add sign images --- resource/sign_textures.py | 90 ++++++++++++++++++ viewer/images/README.md | 7 ++ viewer/images/bg/acacia_hanging_sign.png | Bin 0 -> 321 bytes viewer/images/bg/acacia_hanging_wall_sign.png | Bin 0 -> 232 bytes viewer/images/bg/acacia_sign.png | Bin 0 -> 441 bytes viewer/images/bg/acacia_wall_sign.png | Bin 0 -> 328 bytes viewer/images/bg/bamboo_hanging_sign.png | Bin 0 -> 384 bytes viewer/images/bg/bamboo_hanging_wall_sign.png | Bin 0 -> 244 bytes viewer/images/bg/bamboo_sign.png | Bin 0 -> 564 bytes viewer/images/bg/bamboo_wall_sign.png | Bin 0 -> 459 bytes viewer/images/bg/birch_hanging_sign.png | Bin 0 -> 363 bytes viewer/images/bg/birch_hanging_wall_sign.png | Bin 0 -> 239 bytes viewer/images/bg/birch_sign.png | Bin 0 -> 460 bytes viewer/images/bg/birch_wall_sign.png | Bin 0 -> 341 bytes viewer/images/bg/cherry_hanging_sign.png | Bin 0 -> 311 bytes viewer/images/bg/cherry_hanging_wall_sign.png | Bin 0 -> 224 bytes viewer/images/bg/cherry_sign.png | Bin 0 -> 442 bytes viewer/images/bg/cherry_wall_sign.png | Bin 0 -> 323 bytes viewer/images/bg/crimson_hanging_sign.png | Bin 0 -> 371 bytes .../images/bg/crimson_hanging_wall_sign.png | Bin 0 -> 235 bytes viewer/images/bg/crimson_sign.png | Bin 0 -> 531 bytes viewer/images/bg/crimson_wall_sign.png | Bin 0 -> 392 bytes viewer/images/bg/dark_oak_hanging_sign.png | Bin 0 -> 307 bytes .../images/bg/dark_oak_hanging_wall_sign.png | Bin 0 -> 240 bytes viewer/images/bg/dark_oak_sign.png | Bin 0 -> 416 bytes viewer/images/bg/dark_oak_wall_sign.png | Bin 0 -> 315 bytes viewer/images/bg/jungle_hanging_sign.png | Bin 0 -> 412 bytes viewer/images/bg/jungle_hanging_wall_sign.png | Bin 0 -> 242 bytes viewer/images/bg/jungle_sign.png | Bin 0 -> 451 bytes viewer/images/bg/jungle_wall_sign.png | Bin 0 -> 308 bytes viewer/images/bg/mangrove_hanging_sign.png | Bin 0 -> 329 bytes .../images/bg/mangrove_hanging_wall_sign.png | Bin 0 -> 224 bytes viewer/images/bg/mangrove_sign.png | Bin 0 -> 451 bytes viewer/images/bg/mangrove_wall_sign.png | Bin 0 -> 342 bytes viewer/images/bg/oak_hanging_sign.png | Bin 0 -> 339 bytes viewer/images/bg/oak_hanging_wall_sign.png | Bin 0 -> 225 bytes viewer/images/bg/oak_sign.png | Bin 0 -> 440 bytes viewer/images/bg/oak_wall_sign.png | Bin 0 -> 332 bytes viewer/images/bg/spruce_hanging_sign.png | Bin 0 -> 345 bytes viewer/images/bg/spruce_hanging_wall_sign.png | Bin 0 -> 236 bytes viewer/images/bg/spruce_sign.png | Bin 0 -> 421 bytes viewer/images/bg/spruce_wall_sign.png | Bin 0 -> 316 bytes viewer/images/bg/warped_hanging_sign.png | Bin 0 -> 374 bytes viewer/images/bg/warped_hanging_wall_sign.png | Bin 0 -> 236 bytes viewer/images/bg/warped_sign.png | Bin 0 -> 531 bytes viewer/images/bg/warped_wall_sign.png | Bin 0 -> 394 bytes viewer/images/icon/acacia_hanging_sign.png | Bin 0 -> 268 bytes .../images/icon/acacia_hanging_wall_sign.png | Bin 0 -> 327 bytes viewer/images/icon/acacia_sign.png | Bin 0 -> 301 bytes viewer/images/icon/acacia_wall_sign.png | Bin 0 -> 237 bytes viewer/images/icon/bamboo_hanging_sign.png | Bin 0 -> 391 bytes .../images/icon/bamboo_hanging_wall_sign.png | Bin 0 -> 469 bytes viewer/images/icon/bamboo_sign.png | Bin 0 -> 416 bytes viewer/images/icon/bamboo_wall_sign.png | Bin 0 -> 348 bytes viewer/images/icon/birch_hanging_sign.png | Bin 0 -> 273 bytes .../images/icon/birch_hanging_wall_sign.png | Bin 0 -> 340 bytes viewer/images/icon/birch_sign.png | Bin 0 -> 298 bytes viewer/images/icon/birch_wall_sign.png | Bin 0 -> 235 bytes viewer/images/icon/cherry_hanging_sign.png | Bin 0 -> 280 bytes .../images/icon/cherry_hanging_wall_sign.png | Bin 0 -> 347 bytes viewer/images/icon/cherry_sign.png | Bin 0 -> 298 bytes viewer/images/icon/cherry_wall_sign.png | Bin 0 -> 229 bytes viewer/images/icon/crimson_hanging_sign.png | Bin 0 -> 284 bytes .../images/icon/crimson_hanging_wall_sign.png | Bin 0 -> 341 bytes viewer/images/icon/crimson_sign.png | Bin 0 -> 340 bytes viewer/images/icon/crimson_wall_sign.png | Bin 0 -> 262 bytes viewer/images/icon/dark_oak_hanging_sign.png | Bin 0 -> 276 bytes .../icon/dark_oak_hanging_wall_sign.png | Bin 0 -> 332 bytes viewer/images/icon/dark_oak_sign.png | Bin 0 -> 302 bytes viewer/images/icon/dark_oak_wall_sign.png | Bin 0 -> 244 bytes viewer/images/icon/jungle_hanging_sign.png | Bin 0 -> 272 bytes .../images/icon/jungle_hanging_wall_sign.png | Bin 0 -> 335 bytes viewer/images/icon/jungle_sign.png | Bin 0 -> 315 bytes viewer/images/icon/jungle_wall_sign.png | Bin 0 -> 238 bytes viewer/images/icon/mangrove_hanging_sign.png | Bin 0 -> 276 bytes .../icon/mangrove_hanging_wall_sign.png | Bin 0 -> 337 bytes viewer/images/icon/mangrove_sign.png | Bin 0 -> 299 bytes viewer/images/icon/mangrove_wall_sign.png | Bin 0 -> 234 bytes viewer/images/icon/oak_hanging_sign.png | Bin 0 -> 289 bytes viewer/images/icon/oak_hanging_wall_sign.png | Bin 0 -> 345 bytes viewer/images/icon/oak_sign.png | Bin 0 -> 298 bytes viewer/images/icon/oak_wall_sign.png | Bin 0 -> 237 bytes viewer/images/icon/spruce_hanging_sign.png | Bin 0 -> 274 bytes .../images/icon/spruce_hanging_wall_sign.png | Bin 0 -> 332 bytes viewer/images/icon/spruce_sign.png | Bin 0 -> 289 bytes viewer/images/icon/spruce_wall_sign.png | Bin 0 -> 233 bytes viewer/images/icon/warped_hanging_sign.png | Bin 0 -> 296 bytes .../images/icon/warped_hanging_wall_sign.png | Bin 0 -> 353 bytes viewer/images/icon/warped_sign.png | Bin 0 -> 327 bytes viewer/images/icon/warped_wall_sign.png | Bin 0 -> 244 bytes 90 files changed, 97 insertions(+) create mode 100755 resource/sign_textures.py create mode 100644 viewer/images/README.md create mode 100644 viewer/images/bg/acacia_hanging_sign.png create mode 100644 viewer/images/bg/acacia_hanging_wall_sign.png create mode 100644 viewer/images/bg/acacia_sign.png create mode 100644 viewer/images/bg/acacia_wall_sign.png create mode 100644 viewer/images/bg/bamboo_hanging_sign.png create mode 100644 viewer/images/bg/bamboo_hanging_wall_sign.png create mode 100644 viewer/images/bg/bamboo_sign.png create mode 100644 viewer/images/bg/bamboo_wall_sign.png create mode 100644 viewer/images/bg/birch_hanging_sign.png create mode 100644 viewer/images/bg/birch_hanging_wall_sign.png create mode 100644 viewer/images/bg/birch_sign.png create mode 100644 viewer/images/bg/birch_wall_sign.png create mode 100644 viewer/images/bg/cherry_hanging_sign.png create mode 100644 viewer/images/bg/cherry_hanging_wall_sign.png create mode 100644 viewer/images/bg/cherry_sign.png create mode 100644 viewer/images/bg/cherry_wall_sign.png create mode 100644 viewer/images/bg/crimson_hanging_sign.png create mode 100644 viewer/images/bg/crimson_hanging_wall_sign.png create mode 100644 viewer/images/bg/crimson_sign.png create mode 100644 viewer/images/bg/crimson_wall_sign.png create mode 100644 viewer/images/bg/dark_oak_hanging_sign.png create mode 100644 viewer/images/bg/dark_oak_hanging_wall_sign.png create mode 100644 viewer/images/bg/dark_oak_sign.png create mode 100644 viewer/images/bg/dark_oak_wall_sign.png create mode 100644 viewer/images/bg/jungle_hanging_sign.png create mode 100644 viewer/images/bg/jungle_hanging_wall_sign.png create mode 100644 viewer/images/bg/jungle_sign.png create mode 100644 viewer/images/bg/jungle_wall_sign.png create mode 100644 viewer/images/bg/mangrove_hanging_sign.png create mode 100644 viewer/images/bg/mangrove_hanging_wall_sign.png create mode 100644 viewer/images/bg/mangrove_sign.png create mode 100644 viewer/images/bg/mangrove_wall_sign.png create mode 100644 viewer/images/bg/oak_hanging_sign.png create mode 100644 viewer/images/bg/oak_hanging_wall_sign.png create mode 100644 viewer/images/bg/oak_sign.png create mode 100644 viewer/images/bg/oak_wall_sign.png create mode 100644 viewer/images/bg/spruce_hanging_sign.png create mode 100644 viewer/images/bg/spruce_hanging_wall_sign.png create mode 100644 viewer/images/bg/spruce_sign.png create mode 100644 viewer/images/bg/spruce_wall_sign.png create mode 100644 viewer/images/bg/warped_hanging_sign.png create mode 100644 viewer/images/bg/warped_hanging_wall_sign.png create mode 100644 viewer/images/bg/warped_sign.png create mode 100644 viewer/images/bg/warped_wall_sign.png create mode 100644 viewer/images/icon/acacia_hanging_sign.png create mode 100644 viewer/images/icon/acacia_hanging_wall_sign.png create mode 100644 viewer/images/icon/acacia_sign.png create mode 100644 viewer/images/icon/acacia_wall_sign.png create mode 100644 viewer/images/icon/bamboo_hanging_sign.png create mode 100644 viewer/images/icon/bamboo_hanging_wall_sign.png create mode 100644 viewer/images/icon/bamboo_sign.png create mode 100644 viewer/images/icon/bamboo_wall_sign.png create mode 100644 viewer/images/icon/birch_hanging_sign.png create mode 100644 viewer/images/icon/birch_hanging_wall_sign.png create mode 100644 viewer/images/icon/birch_sign.png create mode 100644 viewer/images/icon/birch_wall_sign.png create mode 100644 viewer/images/icon/cherry_hanging_sign.png create mode 100644 viewer/images/icon/cherry_hanging_wall_sign.png create mode 100644 viewer/images/icon/cherry_sign.png create mode 100644 viewer/images/icon/cherry_wall_sign.png create mode 100644 viewer/images/icon/crimson_hanging_sign.png create mode 100644 viewer/images/icon/crimson_hanging_wall_sign.png create mode 100644 viewer/images/icon/crimson_sign.png create mode 100644 viewer/images/icon/crimson_wall_sign.png create mode 100644 viewer/images/icon/dark_oak_hanging_sign.png create mode 100644 viewer/images/icon/dark_oak_hanging_wall_sign.png create mode 100644 viewer/images/icon/dark_oak_sign.png create mode 100644 viewer/images/icon/dark_oak_wall_sign.png create mode 100644 viewer/images/icon/jungle_hanging_sign.png create mode 100644 viewer/images/icon/jungle_hanging_wall_sign.png create mode 100644 viewer/images/icon/jungle_sign.png create mode 100644 viewer/images/icon/jungle_wall_sign.png create mode 100644 viewer/images/icon/mangrove_hanging_sign.png create mode 100644 viewer/images/icon/mangrove_hanging_wall_sign.png create mode 100644 viewer/images/icon/mangrove_sign.png create mode 100644 viewer/images/icon/mangrove_wall_sign.png create mode 100644 viewer/images/icon/oak_hanging_sign.png create mode 100644 viewer/images/icon/oak_hanging_wall_sign.png create mode 100644 viewer/images/icon/oak_sign.png create mode 100644 viewer/images/icon/oak_wall_sign.png create mode 100644 viewer/images/icon/spruce_hanging_sign.png create mode 100644 viewer/images/icon/spruce_hanging_wall_sign.png create mode 100644 viewer/images/icon/spruce_sign.png create mode 100644 viewer/images/icon/spruce_wall_sign.png create mode 100644 viewer/images/icon/warped_hanging_sign.png create mode 100644 viewer/images/icon/warped_hanging_wall_sign.png create mode 100644 viewer/images/icon/warped_sign.png create mode 100644 viewer/images/icon/warped_wall_sign.png diff --git a/resource/sign_textures.py b/resource/sign_textures.py new file mode 100755 index 0000000..e0b548d --- /dev/null +++ b/resource/sign_textures.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +import shutil +import sys + +from PIL import Image + +MATERIALS = [ + 'acacia', + 'bamboo', + 'birch', + 'cherry', + 'crimson', + 'dark_oak', + 'jungle', + 'mangrove', + 'oak', + 'spruce', + 'warped', +] + +in_dir = sys.argv[1] +out_dir = sys.argv[2] + +def sign_bg_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/entity/signs/{material}.png' + out_path = f'{out_dir}/bg/{material}_sign.png' + out_path_wall = f'{out_dir}/bg/{material}_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (24, 26)) + out_image.paste(in_image.crop((2, 2, 26, 14)), (0, 0)) + out_image.paste(in_image.crop((2, 16, 4, 30)), (11, 12)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (24, 12)) + out_image.paste(in_image.crop((2, 2, 26, 14)), (0, 0)) + out_image.save(out_path_wall) + +def hanging_sign_bg_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/gui/hanging_signs/{material}.png' + out_path = f'{out_dir}/bg/{material}_hanging_sign.png' + out_path_wall = f'{out_dir}/bg/{material}_hanging_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (16, 14)) + out_image.paste(in_image.crop((0, 2, 16, 16)), (0, 0)) + out_image.save(out_path) + + shutil.copyfile(in_path, out_path_wall) + + +def sign_icon_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/item/{material}_sign.png' + out_path = f'{out_dir}/icon/{material}_sign.png' + out_path_wall = f'{out_dir}/icon/{material}_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (13, 14)) + out_image.paste(in_image.crop((2, 2, 15, 16)), (0, 0)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (13, 9)) + out_image.paste(in_image.crop((2, 2, 15, 11)), (0, 0)) + out_image.save(out_path_wall) + + +def hanging_sign_icon_image(material): + in_path = f'{in_dir}/assets/minecraft/textures/item/{material}_hanging_sign.png' + out_path = f'{out_dir}/icon/{material}_hanging_sign.png' + out_path_wall = f'{out_dir}/icon/{material}_hanging_wall_sign.png' + + in_image = Image.open(in_path) + + out_image = Image.new('RGBA', (14, 12)) + out_image.paste(in_image.crop((1, 3, 15, 15)), (0, 0)) + out_image.save(out_path) + + out_image = Image.new('RGBA', (14, 14)) + out_image.paste(in_image.crop((1, 1, 15, 15)), (0, 0)) + out_image.save(out_path_wall) + +for material in MATERIALS: + sign_bg_image(material) + hanging_sign_bg_image(material) + sign_icon_image(material) + hanging_sign_icon_image(material) diff --git a/viewer/images/README.md b/viewer/images/README.md new file mode 100644 index 0000000..2e840f1 --- /dev/null +++ b/viewer/images/README.md @@ -0,0 +1,7 @@ +# README + +The images in this directory are assets directly taken from Minecraft, or are derived from Minecraft +assets. They are copyrighted by Mojang/Microsoft, and are used in accordance with the +[Minecraft Usage Guidelines](https://www.minecraft.net/en-us/usage-guidelines). + + diff --git a/viewer/images/bg/acacia_hanging_sign.png b/viewer/images/bg/acacia_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..33e319123c44d09445c845a1299c2bf9db230a3f GIT binary patch literal 321 zcmV-H0lxl;P)XQu{alw*QQ0 z#&E37{e#~=K6_47Iaf)uUf-R<&dyco=Hs(DizJ9bxV|!Z21{RMU?J>=Kr;M>^IEIe3nnV4bQir ziUbl!=?{n@3Rv#55G62qS?bWcSJT1}R^?8z#~}rG1MY T#;oaB00000NkvXXu0mjf1pX7P60{i^uaftz<-x8-4AUc?~c!la_a zz%*Na@4BSQ*Kf?{{XYFh>y&W>M`W@Ox44{~97p!u8J&}yTsTvcgPfN8zF+_CA4kf{ aPJ8v)y2q>=ugL%%z~JfX=d#Wzp$P!E2~Q3H literal 0 HcmV?d00001 diff --git a/viewer/images/bg/acacia_sign.png b/viewer/images/bg/acacia_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc6e4701b043a5d7943e9a690aff8b11b63628c GIT binary patch literal 441 zcmV;q0Y?6bP)Kyq{Y6MD49skiNK2X!CsoVPT;jToD_4rd zTM|e2?%CftgW3JvCK?H_;!HtbcYP~X6#yVrYuNl0jYLx%kPlv`Y7Hqoq-qUSR)_&e z;Wc#u`Sm-jeu^{Iq@_wh3a>VAO;UJJC3beD?_Sp-KP7p&Qr<)>*RaZDy-9mO#bABn|AzP^k`57Fmi%JdVnVy=9b^&du+ z6|TZ@)6|@g%}*`EwwUiS(DM9BmV0+zSC`*OuP;xV=f{WclmqgPm$bSJC-_O1PMdNH zczgeFYVI6xF30@_oFb=yWHEO>#s4}%QT+BB006f)*Zlf$wC|U%)AH j4(Rm+$ztx*902|RONs&Lteo+u00000NkvXXu0mjfdvL|Q literal 0 HcmV?d00001 diff --git a/viewer/images/bg/acacia_wall_sign.png b/viewer/images/bg/acacia_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..f7ec6214ecad2b96dd79e9de5f366b18faf5d7a5 GIT binary patch literal 328 zcmV-O0k{5%P)-@25Jex%GV++HNI{p{bxxD>Ek@(r5(myQ9A%!IZMHCyNBmLt|Lua^Ng2EW3!G`MJ_pBT<`JY1gpEv zZ50Y*71|fQ0$E;~+Td3BB-No`ZE(B^EWOF`qHg0}oTUKR`CZ&TdROjbcjYTw?`3w$o4n^Vx{$Z-nW1u=3Qra+`}-V2M(umCca~0BF?> z%4YTGwNo90fuHGFz_%A*#QPcd3?e18OB*xbO0000UUzJ@AlQ6yI1&l2Bg}#1gq-U_AqpR0xD%J3GxeOaCmkj4alkXba4!+xRq=W z`SwMU(xzLj3zPkWpY!zE=JN0?my}RAlEtR6v5nE|O=5$9&cSnPdgqq$@tk@4)OdM# zn1q2rtHkad61%kwHu!j-ev$FIAR&R1ag|{itC7{|bf5KeI74I}F!>QrWkQD}YC8z^M>cc_= zrp?edN#v1t@4b5*eZBfvI_?C=Ly9n(p&3$U=mulKAm(^Tq3@*n(D(Zd*4qT!8@0gu zr?U0WJ<(dvNda0Ab50y{0KmJqfg%W_83I1VJY2zXC%sDhRK{^&)-_hj3{jOqz^4EJ zdUy8|QIui5&5@H00KjKsV81h$J<8v$%k_S}zJbri=ARY>j{5^bh`K}<=P4ZbtaZ_I zS@iC4rC#qF0x2`x?hc^EgE_>#5rh!fKb6QyVU+1wCo6?*_Mq7>$5o`%X9NH+4_)J; zrrKt$yUP1Q%FJZpGoms8fb}--b&*zTTvBDF)ps)kl*1O4MAJ>DPO4qxvvCVU3xfG#ia2iA^x~YtanE`u zwX3$T4^n0TSKr4&ieLAYO?^hdSb${p0Pcxajq5sZ+SA&=bZf8A=t;JUt55ICFP}e@ z!^k?`*nqh=LL6UOiLxTlhOh}b45{PWa*27kvLdj`Ks{oUVc<&%x>Nqo30@Lb1mc(v zK6ZaaKnr4Zxi!K6--A~lwCkG$i`nV>|6II!5B>m*rv-D5Y(V$`00000$ literal 0 HcmV?d00001 diff --git a/viewer/images/bg/bamboo_wall_sign.png b/viewer/images/bg/bamboo_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..818286295f6828c4244b9e993a6acb0772825f64 GIT binary patch literal 459 zcmV;+0W|)JP)qe)PyCr( z&g>2+zixk?!{~z3u_VnF^h4{4VMv+$7jrt6*qXv7-Mwtt>{h7R!~-8b&fZ?l3h%rQ z8blMgyy8>?@Z)=89!RqViJG%a*M!lIam;M5S8Idq&!9iAFfxydSOx$r)5y7~&$i#|A@i}&x^gOF z85jisn_WHXBFogdq*Z0v50!y&*iGwr@va-v%*-Io7GHWjQ~;1=zH^2V%d(q6o_`}z zbAJC>@wC5h0mc!1H+^+d=b~6nJ&b4qmN#?qyl2zvD?u1tj{ejk+p#%lU4b&|)3N0B zrL}1+1Efq?t=~|y!s~I@=dJ%+dzfMGZI1oPe*q|*@s@4RMi>A9002ovPDHLkV1j=h B)L;Mr literal 0 HcmV?d00001 diff --git a/viewer/images/bg/birch_hanging_sign.png b/viewer/images/bg/birch_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4972ce7a71f9a87c0f4edf5abf42f560328590 GIT binary patch literal 363 zcmV-x0hIoUP)MJYI=`q%SLYh!>z|8?`?>+Z*XR2IK*d+? zqbhfFb5*(X?#;g9@%3Y%02Z?pV>Gc&TC6Z6n=iQ@U$+I@5}R4Zw-bU$k=qrUP2pPr zD2r{IjFf96VT`7!YXJ0U=A77IgrWPZwj}^XpFr>dntkPHgh*(* zdDp=C2}7EFMX}DEK#ztjW+_3WSj^IPz|o3FAQQyD5H)p;F`C@2JpcM=`>#QyPKt#@ zkA}oLalTJ101i(k36agLcV_b?HnaW`qa>8({q z))ehpl(}(6f@eUgolCH)j_qGHH5Q;E#*!evUYyJIS8;` z*dJe!KGhd5fPe2MG#Hs%S1>A8ev?dlTO}T zq~O^E?woVaopUqV{oR%DTpKEaFhRM-`4#{W#cAQJj;q$Rr-y67`4&-}!eIuYIK_r* zuuK7m82|v&?A4mddYfM7d|PPXFasO@Q^JmjUY_&rd@h{He128 z833)2;cB_NSt;Aq^1JYroF;v~gA5jc>c1U?qLO(XuTHP4Wc6w)N!DZ>Zt~6hxmT6A37clm^Nu?cOUVNS{OG3XyVzl(|9ZX?;%pe80`sj+|_anj1i^GQ3{?Z??(ydbzDu z(H!~R3>IX-{%zOIyvsbK3;DG#_OIrPgp)Y7F~t13Zh8unP?fnG&|nqMPnj#)c2h88 n;bVUH4+Kk|3-0}k5Vrn5N3`3BIZ6==00000NkvXXu0mjf89bLZ literal 0 HcmV?d00001 diff --git a/viewer/images/bg/cherry_hanging_sign.png b/viewer/images/bg/cherry_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..2d6cf71ccc07da7c4289809da8055311185b69c1 GIT binary patch literal 311 zcmV-70m%M|P)SJ|QY_`E8_`cgpGeqRNbz7+txzrKx*co7()008X! z5CzhAxPN(G5dcWvA<7W|K+JI7n1dk76tb>2XLkeuQ3S*czNw*s&U0?$d{&Vi6jWHx z(-(XO_P<|qK!`sG5%9E4ZM3R3)E0Km8hF}fCc6iFo;CR^g^3yKdXvmU5IFK@)yu%t zpj?jgj3I{f4I6A#=?=<}_SB#~HH&Z*Nla>>7a`8+x>O64`U590j}WhNI}rc?002ov JPDHLkV1jYFgeL$1 literal 0 HcmV?d00001 diff --git a/viewer/images/bg/cherry_hanging_wall_sign.png b/viewer/images/bg/cherry_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..a7325f34714f9ad4b4f0cd39dae864b33c01241a GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX1=6ZIwstPTo&l+6TN^HQ z_Fn6sd~?doJ2U3ppRn2m9c!6Ny=VQJHjuxM*Jo8_i z|8>^bP0l+XkKxZG2D literal 0 HcmV?d00001 diff --git a/viewer/images/bg/cherry_sign.png b/viewer/images/bg/cherry_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..91b1949046b4aa2d4d13904804840d89b7028e67 GIT binary patch literal 442 zcmV;r0Y(0aP)e3Eu{CKC1-TE74sVapkQxheC0m&VbGls^2liFKipYQqk z-m@dJmuDl=1Qezy;m&F>r)rak6hxa6N&$6s+JSTWljy+9O`fAG8J z;iV}`?CT04c@a4}w}q}0AUd+^eliBlQq`clpX+q$h^M#4+0CF$B4=suWzT_K!K?WRU+ zd(SW7z3+g6^xS2c_s;)WEM{}Fn9U6bBRR$6^tKs%UXQuq5CA|jh*|Zl4nFb~25P_} zV0Cam8nHHK6V$r{n}8+JMsL^zY?HYjusV1cPnyAhUemnzX4SI@xSO*Hh9OH)KEdQ} keEeNp8LT5MzcO|gKiQAn2ZzXpumAu607*qoM6N<$f+xGixc~qF literal 0 HcmV?d00001 diff --git a/viewer/images/bg/cherry_wall_sign.png b/viewer/images/bg/cherry_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..48d9511b151578c15989ccb4b0f20ff68348c19a GIT binary patch literal 323 zcmV-J0lfZ+P)a2J!><`%d=&zRq{ssH{8)U}WZ z!-zP~)o}CAp7$u}nYvboVGSe?-h+%m@E)_9PyrxgbPo3UPSzCl9ES0=tEC8QKud{? z0o=6ygJ}1wNa*?ZazQG1*Wm81n%__7&6!k>evXGwVk{_1QPOi5M$B$PEne7&^D-Et z5MSg8pr~i+T2!Kr414FR21g$OfGs^=g>B>o?-~F|^8LqMbQwK2pC8(IXIW?JRf>5= z&uS*t807d$Ef(wCEss(3tSp7=Vqkn>W;dbU?{(4Oy`J+eefAzm2+zO1&z|{GJOIqD V#mlX_=I#Ih002ovPDHLkV1iJFl;!{c literal 0 HcmV?d00001 diff --git a/viewer/images/bg/crimson_hanging_sign.png b/viewer/images/bg/crimson_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..aa3dabe922b5d3c96d140eb20b867bd4d57ba5f8 GIT binary patch literal 371 zcmV-(0gV2MP) z4q}E%VXOsUs1yL*H-LHZ%bteUk9QFPd~ObsR<;Hpvs?0AgRz!nnFlswEnmeC0Q=VU zEdY#_KA^X*$5^>KScov}Z;=Si zvdn|*ZUg|2IvJ%%d61d!n$YXs0YK^G1mKHU2#mFil_nzYEq1MVf}Vm%ik>uYWnngf zRZ1OH{W~H+xvPSIFIP%UX1Af&wF@A9QWplL6XxshLye(4TJr=-JIpcn@dx~dp+I?E RFP8uS002ovPDHLkV1iWvq0|5X literal 0 HcmV?d00001 diff --git a/viewer/images/bg/crimson_hanging_wall_sign.png b/viewer/images/bg/crimson_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..35a78922998204e89892e7117b11534d6dff7054 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnY1=6ZIwstPTo&l*9I-YeV zK@AqcO%_p|meJGfk`}mR{L^D)2P$GL3GxeOaCmkj4alkRba4#fkY#N+D9C6i(zgH4 zW_9Be&(5WkEaHp`=!#l#pp!3*HHY<6*?N`pEuWt<)Y+D;-BacD(}BsOgJ*&u-vbV2 zgIz~8{a063UfzDy=-1(vwtYu)ikc&~cZjj?b?mVg7ZW`+r^CtRQEb|$sM^mtEqU(~ cZGXP!mzrjz;qvjHJJ1abp00i_>zopr0Nqkk!~g&Q literal 0 HcmV?d00001 diff --git a/viewer/images/bg/crimson_sign.png b/viewer/images/bg/crimson_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..08e23220070570a027a2b4628305bb2a54b122a5 GIT binary patch literal 531 zcmV+u0_^>XP)!EA#}E(seZX$@_ale+-jyrs*$IpK!jUOxP@gL zaqKEQ+hKa7N>aGh0A(%63ZAKT>4ka0+Y5p$s&(VpPT8$5CtR+V*9Qod(r_Q z&Qh$rSjervguHmJ)~y_r;}BpPbY>zWRMzt5u_lcPYM{0HCCJz&+Fp zUrzX`*TlON&vuA+DXT%7tYqEu6{%5MOMQg;5FYz9eO52_X0_uC;FL&2dPsx83hoIu|G!zjU4oCr zd!wY_Iy*ecYBC9o74cjv3=|K^P5tET>MOm!@+T6xioy*~NF>FlU=_U@Nw%b%DtPb0@&^>>!oG+SKMgWwiB53SE6Z{Dp`|Rg~22>PLn#$H5 z@Qdj3IFK@8o<`<+&o22>?opf7)xmNM*v8K2V-3;xM8-R}@FhnmutCwX7Wq zhrxzLHslwMtuKvQOjA`~2clI!|74#pKylP9dw({!{GyMq8?b)~(AgkRz4LK?@tJ?$++(nO m9b2&bzr+4SyCUys`ux9E(e_FzKJ<0~00008MAls+THdc8T-`=`(3A8+rUXF+mb0(>9(vzkj^1+abGM1ZEQlHkL#j{IIU z=L63#uT=x!e89~O*Ii5hWm98YS2zzYMA{iN*a_<=Jwg&k&(&&KjevcKsm^s%ng%;1 z@i>O`VhL0LIT9=*|0QcvVqdnNgD(7XYN}0q{z4IeU!Y? jPqTAp7tdIcz`C!pL$-He)vpGiLl`_={an^LB{Ts5`8!uH literal 0 HcmV?d00001 diff --git a/viewer/images/bg/dark_oak_sign.png b/viewer/images/bg/dark_oak_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..8b1307d9f89ae16eb91240b74a278373ecf8b218 GIT binary patch literal 416 zcmV;R0bl-!P)6*MNmWYs*I_%2s-bS&@@8f&RMXCW};Zw?rKJ?{u-31Rfant22p|PS5T{CLq z2j*ZdjGqR^SMvqfDh*Mc+svkeA9VR^25gG}%p*aDY>E!?z2zd+vG4&}Jv?v5JaDaaRo?JRP8lA=aw(X|Njl@!Hu*Axd&L+K^QU@tntixnbn&6^&<|ABggm< zww%ln059R`Zcm$Yc4!X87uCO8zv19NUcdGJln~ISK#2mW!0r zI23t|CBGdX%R=M}Glj@k|CWk+3HVKyIv3rAl0WT%Li2?EOwX|O{{iZq$;jY~4ygbD N002ovPDHLkV1maCkAMIG literal 0 HcmV?d00001 diff --git a/viewer/images/bg/jungle_hanging_sign.png b/viewer/images/bg/jungle_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..ecf1e87821b9d05c83e6089417bd40fe06091d78 GIT binary patch literal 412 zcmV;N0b~A&P)+_4NHGkADuGekGrrU6hL`6xa3GTD+E8uC2HT8sCdf&{HK z^x2w1b^a#I81;uO2(Z?+dfwAC4FKiJZRH^X`zoU%FkQ~cqNY-T(m5F&pi)8dnKBm< z)m?T0g%Bu6C|8b31<7TkQLT;5k-Q%XZ8x zYLX-oauzj<#iI2ezsVxt{RiD@?SNPR{oAY^P*V$Lw>|+K6RtVWgm7d40000ORQ6Vg5JOvMd1rY-EmYeCPJ+yrAYF2ut!t=I~t) z8<|5Y4Y%8Y?|PNK`Z60|#Or0*NJVpi?|P6*SFSRzH(}!osdS}DDvh@^K^>3JPrqt5 z)cImMo^18FZifxq_#$2}K`OE=DF@d5Bv3B&rK_9xA{vZ9IRru2=r09qE&+fxzH@zX zTC{rb4~Xe_QvTSywAKIG2LOU30aY7FHq}fr)l6;^UyxViD+L%0MrFWKX^>K?*)p>6 zcb)+Yi}|cr%xA2F1gH7#^&N2{Sx4=0n&U*`;Lv3)U@3?~7f`JEyaheC!<)`skV=gY z^~GAi$^Za{J+HmV082rfNW5rX2rLCh!vH78ebxe&f>oMhmFDe@23QLEk%#>*>n5Ip t`-cqQ+S%QLDCE6j_JYqY(DQkZ?FZSv^rsoE7bXAz002ovPDHLkV1iT_%eMdk literal 0 HcmV?d00001 diff --git a/viewer/images/bg/jungle_wall_sign.png b/viewer/images/bg/jungle_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..6eb610b5928ff182b22c0ff41d4ee3e5e6dcfd88 GIT binary patch literal 308 zcmV-40n7f0P)2jMHdA^fuz-|7PZY zFE}5zeU|2+%Bq0Qrxmlx~hYBFOt4xgrYQC0=G zMbp&gKsQf{z3|IdkMSZ)bFhabS&Zh(g6&HH;1eI5_M84=20uuwmn-w*%hKn6I|l%Q zD*?k8xHdf-rf0KbykJ($l?7&LZVHx4gPYRxb>!p!-oXnhvd&kZX_>qL0000BWhkG#EqEG&TZ5ibJ(odaBK4q^xbo`LQ?qAV?Cro3xSi*+daLHx(9GT}U63 zFq3gH2?4jx)IO!~!=V|--vJrGEiH(tA|xdW0%70Gbc&k5Ep3a+^bWOGY79u?n9bb4Kp#;Fy#jG-TW@%cX9ehb(5m02}&bB2g+(ek}%EH b`^fkQ6`_DE6{Z5X00000NkvXXu0mjfKemSv literal 0 HcmV?d00001 diff --git a/viewer/images/bg/mangrove_hanging_wall_sign.png b/viewer/images/bg/mangrove_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd994833c96e895eef7076852a18644f73fa817 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX1=6ZIwstPTo&l-(db*{C zhE?WLMo}0)=ApRWk@b{(%O}&a*LbG zd-r_r>~!$?{IXMt0fkN(>}OZ5$g9;9?RQ-)SBYuBLIU(`3I-+&Ou?`&b0C#q!ZbJ` z>k87(=Q?G3^#WkRKuDlKRg4J(lxXeB-hHdnBYd7_^A-qMwTy-etF>;@t1pdibTP;H zd@@a(9t%W!D;yCc^76S(D~}bTDp?n#mHecjxzGy0%jYUFKq>*$-Z}iG0ox)#JsS^y z@bPfJ>$W`_DgZe27Y^S&d_I{b&5N#=F`}dSVJZ(ickwy3M6KIkJ7<$AXLDVAPF|6( zbe8Q4vo3SQw^38n6s$Str}+DOkXc)?ev_Yz@3QT^jrZ__;{Ek;H+y?JI268Mry=cF z=9?gVu)w9f=vScE4zvy{9xQM(R>1;11pG7iezMa@(eB14{-Dnl$n-XN27jM4@&KAR;1mD=002ovPDHLkV1jL#%Tcwk3xxPS`K2cwxFWjk1MWyHxlEK%3m^isWy%>ytgFoQ(`S$*B zp1?K)1vxLp;+Q;Sb*mg6_g=RRG6m`2o}mv&NFtYVC#B41hwuS0c8lr z0uia0G6YQ6oJyX4)9Ha;hyG`igg&`*<8Ysc9KL@I*xNqmNUtwfUu101t|$uDp{?rm z5E5gDHU*c0?3pJU-wS&HRlRnefM5YE>EreG*tdOd8~{A?MS*)o zuP;}h7xpYWw1@E~*eB*Cz2=s4#fCDQG40%egNHQetT0lYjtv_+mF zQA{Yp)>^EoI8Dw0*jfufC<4H0y#nCw@p%*gEMDI!Z9|%W0bot#28%p%yq*CzY3@gu z%EVJwH;PaMYbqp)y$DV~qL^87=ISo5;-zi8Wlo^p8E1Pc6SrBj552?5IPx8ow)tmK zMU_*B>ck1CnqKHHbn`3pjq0889rU*j@p@N$|3wP`va<5XzD>>FYbrZ4a^eW lmKy**><<8u1ekr@$1h1un&VF+;Q;^u002ovPDHLkV1j6Sjeh_D literal 0 HcmV?d00001 diff --git a/viewer/images/bg/oak_hanging_wall_sign.png b/viewer/images/bg/oak_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..9212d0787635ef5c56ce50007c651e5ce7555a0c GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnY1=2^CWFDBCv~z02y1t-A z4c;?roF|q#dIqH0xdf}~*uFe_XB$uvV@Z%-FoVOh8)-mJo~MgrNX0GDBO3(|8Hl(X zEN?H~Co+rS@r(mK+|Aowc$p+{c6bOJX4@T|Un;|YJ-1+%wr1*%!}h@pTy6}9SR52$ zPkr22Ki@Vb^P0)bZ6Wh`HCyv9PYhyY9C0r@=Da-JX1q(@O&O|Yw5=Dkp##d3K)KQi0Evo#P4;{?CcP-jmj=vD0Kgyg5wND} z^v-NL$%Z`_0E`*_bv9*sad~l;e~dTlcE-Dg%uPI#UT`x1HBO=$#X;aPmgz;X3gO9a z;lU&-!uaGkzf|eem@(C>^!Ym=P@aG}(>nZ1|9E$m-QS#N^~_)F*pNG&4%SN76Pp?| zftA7gJZ#sX39JpmukZE@)=J}aA4r00001sx5JjIsg(Ed)4Q6qZVj++dY#?XI9l{=DtDGWD&XEh5u&_aeWxI14j~E--&Tk~o z%$LS*Q1%R&%?vjCCOZ;KMM>rD}D|)Ky6r0zM2BF2{#~-nTSB;c@`1b6Dr% zUM{oFvFA5k2+__^>*YKG91oVC-;OP9)vV>R@6Y#9cd5Hs)7FfZ zej^)62v3o4l@*}(Ellk7Y*K!+##aWcF9E2ll14SP=g+Q}^LRX1fF#5J&SuSTUSFQ$ z$7x!Zj2{xrQ*|l7(Z%}Lbdkgahe%^w^PA>&r*Qe~!Suf6^z;}H^|RH+>)l3(7u z@ys)vaC`qaJw3lnT)>hi=EHt}cWL%4PvphdcXO3U&Wi$nzwK4SOI`)=_WCe&7L*9z zv7gYgVxt1-*iY2DLWxux?|A?CtQ0_FEC98T+^j2%cW9}w9@_rYLlr#ZTp3}j6bkL4NaciElF-h2XS40*7hpy)wtWR-r r+xZUE@`rJbVYD2&KH7}EMGf!|w&au6%J{1?00000NkvXXu0mjfg|3~2nJ7AKbLh*2~7YAXH{PS literal 0 HcmV?d00001 diff --git a/viewer/images/bg/spruce_sign.png b/viewer/images/bg/spruce_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5cbab2870257696cc9e9d5d50f1a6bd78627aa GIT binary patch literal 421 zcmV;W0b2fvP)=?UzON?Z6c?GwIo#8x1fbC6-kFcL#BEgt~Hnee?&Z4{PnbYNdH-4lo zGdk8sc3}@}o)$J&`vp)2CR?sM8=pRE%GVCqH32rAtGq7Sr5`L8^Gb*Wz?>hX43bu)K33n5D(`S@G~H5Fv=`t}}FJlNpkeAKVODF`wsRyz0= z|LX>8z3$fl;A(pOPx>>1p&SMk4>m|f5^Z#U2B#p{Aj`k{GbmPJ@c?`SB=F;21sx5JjIsSi%?X;cWJuziM%yh0L#EegXpXgi*fU_;m{+;DAXIswvCZ=4> z0G(^`X+5Q$UQ3!D`J3nCHUn7Oky7ADM>Tsn^Yw96Q?93}t3TM$yWhw`62em?T;&Vk z6AZ6fy_=ff?D3Ta>q~%TazB-(Xa45-xXspf09A(n-OZlA>|oKtb<244yfLrU)%->m z>tEAF5)&LEjd9O!#@B<;55_0>y!NGOh`GvG;z$1S4n)Ee>P*kH_5T9oNXvKIM+U9{ O0000R8Rwt> zF$$dO{&9GCdVV=@rOt7lZ3csfYr7Y5UU~SPOm8A7;~c>zncuX0j;jF-Ki&`da)t7J zj4zSe0APFxK=~VhnN7${&gbh}%>zh&z5!Ur3jm@pBGnqH4f%5A)TA~fqw#UbO*H~Q zC+K5l6Ua?Pahq&h-)y%4*ze+kV84sWvh-qR<@>IW!U(U|B})rz#lbpWAcS&Ydy8hf zb&PVdT`ospS-oBtp^hY}*6yu*2Y`AbC#cyo~&4NQKn<3 zDwJ}r{v8ouyPmuJ)~-;BD2&`&IWEARZT32(-UyhEz5s}I$o3S?3XlirRrPoO1Js(F U;%w=8PXGV_07*qoM6N<$f-(N0&Hw-a literal 0 HcmV?d00001 diff --git a/viewer/images/bg/warped_hanging_wall_sign.png b/viewer/images/bg/warped_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..a80b913b4f57582eccfdc3d702d0b96cf0e4f4cf GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnY1=6-Fm$@vQZ#{Fm*_1xR z-X6p5R=w5=&wx}rmta*LTcfm~*FZ&#B|(0{3=Yq3qyagVo-U3d6}Lo>DGD7j5MaHq z-~Q+}=@diVm2dX_xdj@El6GzQ(K2@1Faj f!zR} literal 0 HcmV?d00001 diff --git a/viewer/images/bg/warped_sign.png b/viewer/images/bg/warped_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..8fdc1811466fdfd0f9516760a56828ad680bef21 GIT binary patch literal 531 zcmV+u0_^>XP)09=GCaDYk(q?!dRDy%GO zxw4u}5w;P-A{mng*oK5&0BeHa07XHmTS^#jvK&u-*tq7r$E z4nhECQqH+8dM7$L)|JW-c}nT|h&<(@vt8#2fATk2olBeEHQAcxO3#NYg$_cxD;tVD zoqvtfV$(LgGdLRS)l8ev#%cQJ4xU6eGX8OYx7EZi3Y;WH2Vs5x+w^X~D1fD$FDG>r zrsd^)0WLb*_`ufXq}Da*-KKoafR{}GbPzI1Vy05kXV^F&qhI?D{&hA@dMo&^-{|Mj z3vHw6SUDtTR&;BFgHwmoS5G%*pw$_NZ$EF&zzov{t_^voE1~>iWnk68bydtwEMV2a zZSJ{M2cKS!DaGT>863Qe`FLpc&g=|4{f+(i@p|HI4FK-#^fza4T@_ZF!+*F%zX4r? V2qbK`zpMZN002ovPDHLkV1lR2_ALMa literal 0 HcmV?d00001 diff --git a/viewer/images/bg/warped_wall_sign.png b/viewer/images/bg/warped_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..86a7cab7ffc5850fd99b43b4577d9de826a6fcc1 GIT binary patch literal 394 zcmV;50d@X~P)*ja_Gl+@>BF5d&{W@K|B~DK@FuzO1B5ITTR*6xrCj} z+u41SIMHgUPEyj0VNqbqC)+jtbVik@bO&Q=-APK^Do^Ry=NfN@NKt2mv@rd9H2YooKaGRh}ZUgwpd7S;DT< zH$LIlzmDcy+IUyH)t4(h9}YPx2Q42hZM-vD%vIB=E!t{q@7&Q#bmjQ- zVcOcnFAAJZj0!^Y{kQS%uqc2F&-<-Wp|5=D7hu=v;{(0@)^Il7wfWTpzH9=Zf{@83 o<|rjY#@6|0{^o!1-`UvsA2SZ)klU!ZLI3~&07*qoM6N<$f-AqeT>t<8 literal 0 HcmV?d00001 diff --git a/viewer/images/icon/acacia_hanging_sign.png b/viewer/images/icon/acacia_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..79c8ee59aa2db7815ae483cc5e194352b4536103 GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^d_c^@!3HFQ8hUO4smq=&jv*Cuk`o-5;^N}|OBOJc zSgJ`JK5^oOy-_dEhLeVh+Bdf4N-OJ0UwkSdDIp=j_w?5P^n`?jA0OYcGlKxTID4Dh zj62Wc_e(a3&reQi(3Ag|N002ovPDHLkV1fc%jzs_f literal 0 HcmV?d00001 diff --git a/viewer/images/icon/acacia_sign.png b/viewer/images/icon/acacia_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..c698b7d3e16b3bdd08af2de3c9dbdcb8f90e7ccc GIT binary patch literal 301 zcmV+|0n+}7P)fggC z*|@aM0SaRY#MpY8o8wCEz0UtVFNj~%&VoxYdw$(p@|xhy)n)bmk)ib`clV=T9luGs zI6tG)KG}MyQ35#awD*_(O3(z8r3XJW0002ANkljpHB<4fLu n=6~Y_`Av-;cmEgt9b z4n?f6@G1_jLEd>E9>l?+*50`$Yinr7?w?~(Lz;Klvr{;YIiV1jf7c?hUkwRVyn}YKI~~9 zsYICm$RU@G&qpof^VAwGHqP1&M^zfH-rJ68eEv1h%KN{j*Mj~s6&Cp5o%F3l`z lN7w1;Uv%}ElYj2<7r)?!lX74GjavW!002ovPDHLkV1k%JwzL2M literal 0 HcmV?d00001 diff --git a/viewer/images/icon/bamboo_hanging_wall_sign.png b/viewer/images/icon/bamboo_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..a23377edec284b4cfc9310c02864fce00ea24789 GIT binary patch literal 469 zcmV;`0V@89P)7>1uqg2n5l^fZAGF%l5kAyeq=EE$B3rRZRXfUTntq(c|8rc?HIEV$lM=um_> zI65en9CybZiI?P}hMX;da|r+CPMdf6zwdv4zW4oJe#tu93&!IS&0`gS;c&>;!!<^C zJphz+hA+*VkURVkAj=A=i$5mmMTx7c9@%Ub*LAt>26&zafU1sSoaZGmodGdaDwTja zc+4e4Q7)H*=o!WTxJ2}UrfJeV#mAfkaQS;DkYxpc@py!&MGp|=Uu}Gs65?|E;}2}x z;@{s}hMt3MTiCY6=KEu+2U^&R0STB!Za6;gKK)|h*$cLIe^RTrSXo&Gz;JwO^%knC zqNFo%tL?6fx{%_zoTSsAkY1dwbmvd=$StSn^d}VZOL42EVv$@t>^Mb+5x+t2400000 LNkvXXu0mjfynfuq literal 0 HcmV?d00001 diff --git a/viewer/images/icon/bamboo_sign.png b/viewer/images/icon/bamboo_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..d8702d1d0fa5a2521307741c8d1cfcdc74d0f911 GIT binary patch literal 416 zcmV;R0bl-!P)YU6vlsPN=k1N@j^i`R8Smz3U@&S2L}fgTokmU;7}YKd=EGA0dx=@r05H{bg`r{ zLGjNmwkEbD#-SLLrr@2c>#du zxj23Z5p3<94dP$)*@Jz68~G&7x`Wfd+?788I-k6BnbAL_|xk>+Nn zFs(A(&P%3SCh4x(L>exgFv%q4GL>Q-+pb_0GpElc!Qf+#a{2}qd7IvGJ;g2n0000< KMNUMnLSTYTe7V5@ literal 0 HcmV?d00001 diff --git a/viewer/images/icon/bamboo_wall_sign.png b/viewer/images/icon/bamboo_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..9af0ac2de38d0103c1e0b2aaef2264c5bb273a65 GIT binary patch literal 348 zcmV-i0i*tjP)3XJW0003aNkljSijT8Pv$xJkzGAC%C4 zD4R(cn-=0wNYGu~bGY}M%RNTF+en14`EP~coQx1Q^=1d9Je2YnOhyFSM=6i}!&~aj z4uSU586j*kwo}ISBaY4=ky3Je_CTxMqgves!1W_q?H;ZlQ4l7!Q^x3b8;RDMf-w0A zR{#`*3GfT+iQ`a%K{vn+ykJLhwDcW!|BD{ zy8pqCf(5l5*5@r3Zag00000NkvXXu0mjfG-P!u literal 0 HcmV?d00001 diff --git a/viewer/images/icon/birch_hanging_wall_sign.png b/viewer/images/icon/birch_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..85f9c2ec551db3d387b258ae220430c03b564e6c GIT binary patch literal 340 zcmV-a0jvIrP)|8Ns-pi74iIlmd_>3AgPN4v&uj*yha_YfS(3gUS1p z$#f6PvIxVFk@rPab?@x_RP%8hC!;}iucZ>(wzF!iYMa-p7I>a#G)=5~20$?G=Qqjk z{PbY|Z|AQkWXi?WqtQ}_H|{+`rumBEVma4$nm1ppOH?6KX3>U@I{={L4(N4<#jshl zDfY`$=%^x!o1UjB5i2g+PbDf)+}i67wY(bTGXEn}p(;#;rixXrqK^9VkO`UYglYl= mpWCVdf`LB+VBpV)!nj^Yvw|p$NwWfgjS-w=F;&S{w9U8tlzKpYJqqK! zPrE&U-8gt+O|4exR7=&o+y7h7OP)Vk17#e%$K|pk)TFTf($}XKozHKzHKeLK8us<{ wEj>hhe2`@6=YTWU~{Y!^3{cK`qY07*qoM6N<$f_y)Qb^rhX literal 0 HcmV?d00001 diff --git a/viewer/images/icon/birch_wall_sign.png b/viewer/images/icon/birch_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..b82e681116fa5bb435d6f7395c11cdd67c6c499c GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(1|(lrEz1H@n><|{Ln`LX?K9+V3J__vKdPAX zqW&v)R%ubewVkRN861DYo19tR@dbWpdG{gD$&>e!+|JN+E17dUzjM#Z`p@K0&ETTz z*Ii*ZtAg#8a+YQMyp|0ASvdk*Co>)>+NyfCtmCD}=DFvc1HH4^uAO9TC@orW!aF|W zti#0VThbUFXzrb4MkCS_by&~9>DkKvIo#g01$+ut3l&w zC3$*#@qAPKS%0CGL@SBtTKiTX?`NKtVnEeOQdTv2mNFVo$g`B~rm@$`s~&r-^&wrB>=t^EsXXttP5zf}kz e_Paj~0UQC!qlXDA^IReT0000>VV(ZR1E_zfJ2gU}&`I%V%S=+L<65(^co2z3aB zfJDRPjyRNDFSP{)|8Tr_?|=8+k7rH0{ZdIm=jjoEG)=iYJf`8a09f^|j!sZg;D|iq zBY9;qnc%uENs^GhKV!=D=5H}=cdzE-`+ms=t$KEqc%E09(bPK6HXjTI18dX7RnG#L zcKanP76ItRn5sM_3l1*MEW0YcJlvyXfszFx&-A&wy{UPs5KB}g3x=bJuouwU+9B)( z%*L^vHXKFzE`?a4#@C&)(fo&v7xr1LS{q;x6Lsop|+f(_)=35;W#*phY?fl{o! z$V34-)BG?yv-1V1k~IJ($6brp>B;V%yLV$Lm!I@7Ir?$t!p#COy?;Q@o?yLlcc&i4 zA```QJaNJC1RcdbAQOd-Vq~HKsIr_ORkCKiqN{3a9UkC+*HL`1)bs(qvn>K+J=$P2 z^cZ`zrau@B|Bolix0lX^y~N`6{peEAX5L-j)?r_;*lc*7fBedbwo=#^gl89IWz~+? wX1ef}!WP|2H2gk1R(~%208B227xnu%Pyhe`07*qoM6N<$f=D!nPyhe` literal 0 HcmV?d00001 diff --git a/viewer/images/icon/cherry_wall_sign.png b/viewer/images/icon/cherry_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..8ca0429bf6e8726221df53e9306bf611b8b0808f GIT binary patch literal 229 zcmV^P)3XJW00022Nkl9rYIM3AXU3q*0*|vWq5IENrktU-Ocg_hvq? zl41ZrcUU(#tyiOO>|PuC#~mNtp$?f1&kMkQyF+D1Xlm=De6&H7l6{ieV3MNp!UaSr zQF(zVB>?ZX!>gniXlj;fFvj8m?z+m0uTS$iz^i={pp8Qdb;@5JjKKidcwr$kig6l&*XO%J>wVB}d3H($JY3P^6#&DFqeY3PnOe30P<&rqwDhSslKiu6dm>P!vUU>tfrB0N%!v8sO*e1VI0xd$A~9 zHm3cvh1TQ3@Q_>P_i=Zls1l+KaHiK0okJ!_!G#wgM?yl^I{2EZM@ ixmOL;)pm3DqUaxC<7U|#8Y+eW0000Gyx%@8<$xHe1I;^Q}kJUgg%BFcj+6r=%OnH!7ikkRTFG0Z4=9s zxR9AnVhjB@=klF1=ZCTS-CmXdtXbUO0x+M?>3kHl&&~nZ$MVezdpMhreq~%-FL7O$ zEX(*5DW;k%xN&QoIF2h0sL5I?iK3`7qp5wYWey}sVja5JWEMcb+p7SU+YJDhC#U}w z6)UCW@#V>~RrC3M$irQvp;9UYujN#;e6!kFEu|!MJW?U_@L)XB%c0}x`dbzN*udYP z`Mw?ue4hYc=YXzfg>g~&SFaAnqgrmp&Q*JNv6PZj2tvox*3@vbSF`Hawzjm-p4n4Y nZ2+-eaI9)p-=>qJ7nObiisO*Y{#yFg00000NkvXXu0mjf4Je&o literal 0 HcmV?d00001 diff --git a/viewer/images/icon/crimson_sign.png b/viewer/images/icon/crimson_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf1ae7e0ee77ddffabd26ca1c013bcb8177b125 GIT binary patch literal 340 zcmV-a0jvIrP)2F)U`j55Ua#amRi2z%eY`aUaL909eY1Qm56<=gFE~=l<>K zs~(`--En^_X_Et-9Mur9l+1iz#TRE$={H}>2vMsXK)tS<8{hW^KWvk~M=ON)@w)SW zRK3B=^k1Ss=Nj@$+srSH&vM6o5~AKYH(&QoTw500003XJW0002ZNkl))H!cCmX6&%2_7qF7(PSQjd=vz^dQ2I2}u%OSM72jqizs!8| zO=UC~-T=}f2f&C>%25h{R;^B2{7f}1a>k1(M&x4wV7Xc`31=kN3zKkWdDV#E zIWDo*0K{73M}Zyi92Y+d@EjL_qhwS@gW)Z?Uiek>{rV9PusQa)buyufQHm;~sdE6DIwy&jc3M$ocHfKfQTxHnJu*Ockg%a-v2mbHXf=hmt0J)09Y=Uyg%G=dU60j8(XCU>*e)}&rN|bpEDQ?NRou- zw>7$&tap4^;{-vV=unfHW#TxF(xa|6X6gsxI5xT_Hkko18xIx0R{Q{99hrNLB@Jo(>08!{MvisFEf9h8IOvt*`ESFu+ zt0@%)_fH=?t3Y+@$nMv2J#GtCw;F{W{?x6kmG<=7p4Cg|TnX9v_pMeffMossrzTw% ez+%1mcjGS(V3`n&rxsBF0000Nkl1Pj6 zR~9A4I<>`Y?lic6aC6%)X7m5+spV^VFwjOlzkmE0^190FD{a@Cg3qeq@oDvI$M1qJ z&-(mk=%#ftiFU!p8wPM{Ou>Fm@-~6 z3M5N%q{}flzF54}z31sSff`-glSzFN)>;g2wrNk(TJ)C3TXg3g@np?YJ-ecq1H!W} zsg!ZM&YY-b=sJ_}Lf1i{G27-QYVlXreqkuL^?h`4`Fk0M{W^^judn!>J(#({eplrQ r|FaM4_dck3t0vCYbo%el;+MQ}abX7q-hC?vdV|5!)z4*}Q$iB}w31*C literal 0 HcmV?d00001 diff --git a/viewer/images/icon/jungle_hanging_sign.png b/viewer/images/icon/jungle_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..ec89fff07f8257102a95c0d3d210063d4c045b0a GIT binary patch literal 272 zcmV+r0q_2aP)ZcKKQL5xyjvD?l5F0_)mLR2C(ow`L6zU7>I zzw@2@yP(N+-IM~od!{swQ_y5sdZ{_oiQi0>ivL2j0G8X;Pa$0vz&nsR%D+50000Qr)s4`EctLpsm{Zo%B zMB4Vfn)1b*tJ}n~&HQ?6Z!oI$W?d9Z0301v$JEjEuYBT}>eBVcFjfmo9s&KW|9G{*cq817OM)qDQ&g9p^# z!zf-@n)d;6J;M`GHJZUOA#>0B|HkvKZ*NvE7E zPJ!kwnSO!h3~&0y=cHQXtX}mbI`;i`ak&ez{g?hczFf^$aGiZ!$IA;keY%nV=l$<} mo>z8zJ$u-@tlA%yUs!~W6zqG$T9OC!0E4HipUXO@geCy8nPJZW literal 0 HcmV?d00001 diff --git a/viewer/images/icon/mangrove_hanging_sign.png b/viewer/images/icon/mangrove_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..f53bf222da33086ace8342d24d0d0a592f3cf0eb GIT binary patch literal 276 zcmV+v0qg#WP)lXrql?z&0lcR+g3l&txsRi3i9P1d-SXHYscZDa5E4^9RO4ceC*iea-C7 zn>X`;BFAwmKIqxg#lyDkO0BBidAd5_d7k#^;>} zL~|WPSbg(h7BVo~Zm?Uu+B@boYL}=GIUIzM4Etp)|4DIaqV9I}m2bLcI__$r z=_0Wburz_c*&%lN)Nykm-x;agI1U2OvojoX30G?Ir-*Jh8~I9)cG#QSjD!!nSQ@vl*+& zE6)>@Hob$x1~qlN-I5*J^i28iJg?NNu5F&F4-AJxW7ow^&j9H6Iwip8G6&%JsQD`> zJ(0rI^~kVf^Dc~VPn;h!SAoGez-zQBZ;@4~A_c#gGZ+VIIGjc*>=$$OU*=zR)HtrL z{H2vJ>EGTMrp_<7hSR9_)@z=n09X=LV!Al^#eBVfy2g|}7pIPTd2w2bbT3kcY5^os jwqHt<1@Qi{_;>Idv6iKaZ^;r{00000NkvXXu0mjfDzuY_ literal 0 HcmV?d00001 diff --git a/viewer/images/icon/mangrove_sign.png b/viewer/images/icon/mangrove_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..467c922f098c01aac3f08f2166f05fa46d3bf2c8 GIT binary patch literal 299 zcmV+`0o4A9P)q-sOO+=T`D3oM;k`(^zL#(oC_Q>03jvba)(h{zBc3W@F7h%iJoMKw~( zTb_0FuI~wE(@6_ZHwFN$aMK@jdw9{KZVXz1-tGwN#_+g!>cBw&;6BS(ih{BBPV!qA*n6EQL{&SGp3XvD2wgR9rl3+HSv}I{Hb-r}i=>hI{kr%(34mp6?DI%?K zYGX!DgBqXD2kCOxYi8k-svqOOo-rZieNfNVp`{ZG3XJW00027Nkl>Q}J8Qx!<3AJ}?jjK}HFRT173s?`P&TaZRh3hA<4RvWrE{0{9&CG5{fu0Mu&_ z7eS@TRM72zShgaE<1aex*OQnBqBvo-J!ow)-{e(gD)3x~C{DC_G@0tK=Q{em+zJ3} zfM(;7_qUcdmhAw~FHiYJ)nENOnoQ4jbIRR5zbI2d6eoDDqpK-%kvpqetJeRmXL72l n4e&clE{wNe1APCi?+*R}C`(~`{oRq)00000NkvXXu0mjfhOK@N literal 0 HcmV?d00001 diff --git a/viewer/images/icon/oak_hanging_wall_sign.png b/viewer/images/icon/oak_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..2bb9dff4474e0a9c3206ee8e0883638ccda22954 GIT binary patch literal 345 zcmV-f0jBKZ@vgI{>U>v*`lqN`HsLC3m84ibOu@<$CHHr&{VMuist4snIkMtBEioXD8 zH8)m_g2hS1#pSgmi{Z`fJ!hu}KQK4gj>kM$W^6WH|Bf z5<~#V0R3)<`zZfSGwv+!@QBBKTnU$h8H(S5P rE6zkz8Q^K+tt|c}8Q|g3|F`iQJ6ws~TX2!D00000NkvXXu0mjfja!!` literal 0 HcmV?d00001 diff --git a/viewer/images/icon/oak_sign.png b/viewer/images/icon/oak_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..41b46a58a2b11ae8efdc0309192c26b857636321 GIT binary patch literal 298 zcmV+_0oDGAP)!MYIAi-6C!;f*qjiI z6}^5``L;HK>nMUS0U!tyJU^}iuA}h$7}rq%%$9;R=yr-lwqjqUAD>_Ifa<&F$6HO` zeE^-VQQ8PWm{j%UEhqi-|23XJW0002ANklYh|7wo;9o0|fs2y6+GP^!s5h#E3P>)zl;YzU>AsYP)^+T$=FvN2F`blV6|kHDx*woQNr2qf`07*qoM6N<$f-B#28UO$Q literal 0 HcmV?d00001 diff --git a/viewer/images/icon/spruce_hanging_wall_sign.png b/viewer/images/icon/spruce_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c872b0fd748cb55781b3d82c822b2fd7768c96 GIT binary patch literal 332 zcmV-S0ki&zP)`R*Grg!^yO*8>SY%Yc3hjSIqCuBdKkrLpH6##wFPag zlxp3h4ge=gMc@68p8i^7R|7@#JXzihsjBk1{pj7^gY5ZOnO`?S71U}zaTiqXU4{T2 n?i;s5e??c7^Y0&=aTlQjmE?l0{sXrk00000NkvXXu0mjf%?ovl literal 0 HcmV?d00001 diff --git a/viewer/images/icon/spruce_wall_sign.png b/viewer/images/icon/spruce_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..69a9ad95ac48bba261dc08e3325ae69aaf95102a GIT binary patch literal 233 zcmV3XJW00026Nkl=KXnUxAg}A z=@bCg31c?v6#y$eAf3WG;Z+Krbc)02ighvr0QSc-QF@`OTcY$b^`3QtDSE>A20$3! zNV0r7Fhx(2<(Q%ez_|vs+xkOQw=7L#KYGBlo@Dv#({~S0I?&e1q!xU10QgcG``{lv jeSg-Afie1FUOz)`xeIfTX8BKf00000NkvXXu0mjf9}HgU literal 0 HcmV?d00001 diff --git a/viewer/images/icon/warped_hanging_sign.png b/viewer/images/icon/warped_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..80dd99e650d28dce790437d0c2602479d2fffb63 GIT binary patch literal 296 zcmV+@0oVSCP)YBID=fRePJycY`Xc8aMDMi%c))^F)W;z}LOI zS?>t|c0-R5pYU6vlsPV?Z5>LI#UMiGp+}k`8%@EaC&{JM;lM>RP&F78jkYrC_Xrh+3i6+Ga>7 zYPk+_Z~mA6H7uUFPKy0D0bIJV2jaob%FuWn+wl>lkp%%6=8&7Rq%TqwcKsDRM@a8 zsy8O@e*^&Ya)~OoTCCP=sM&E1st;ybd{OetU%TyAs!qPETV{Mwgb{wPgJD$^nq1D# zQmEScT8xx~mz+sd9pLl%fn}9K9bR289hCY7XKIA#?efzh00000NkvXXu0mjfaXXsB literal 0 HcmV?d00001 diff --git a/viewer/images/icon/warped_sign.png b/viewer/images/icon/warped_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..4c3530b4bbd0d36439cd7b429c01b0a4fe11999a GIT binary patch literal 327 zcmV-N0l5B&P)UIXeN9TZ$71RQkfqQ%#66c>E~-=!{21($XWnVlR2hd>fin!&AL20=o^ zL`a0|5EHH5A$pd3?tjjA{$C8oBLyI{3ILTCG$q#80C?Y6L1q;yFG!ysF=SRTyShf@ z#S#E8zrQ1xPUs~W!F1B}+aiv90OH6ebe(p=v@Jr{!L+UVpFSam;9%Il!_h9@`2a4LO0gO3y=3H&0Q@3 Z@Btdga>hhx^~L}I002ovPDHLkV1m@KiY@>E literal 0 HcmV?d00001 diff --git a/viewer/images/icon/warped_wall_sign.png b/viewer/images/icon/warped_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..59614c66b1631a307595245cd6d526d7d9fb39a2 GIT binary patch literal 244 zcmV3XJW0002HNklzFV3eknH5mhNpAHeS#wgA8a>5p}Cg1EZN`C|ZisOM~A26sS$v)_O+bE6W zxs+K9K$*p)QP>?go=X~qIG)?=*E5#CU7JBA>8mPF8a$x;o<`wE)4LBaTFenfY04~q u)jwy8^zHwRCvI8MJJ8};v(?i4lmZ^6w_6 Date: Sat, 6 Jan 2024 23:46:32 +0100 Subject: [PATCH 036/152] viewer: allow zooming to level 5 Allow zooming in far enough so neighboring signs don't overlap. --- viewer/MinedMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 0e9abe0..03c3649 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -231,7 +231,7 @@ window.createMap = function () { center: [-z, x], zoom: zoom, minZoom: -(mipmaps.length-1), - maxZoom: 3, + maxZoom: 5, crs: L.CRS.Simple, maxBounds: [ [-512*(mipmaps[0].bounds.maxZ+1), 512*mipmaps[0].bounds.minX], From 989428f78dfedbb18cad647944a6b48d9d4e7501 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 Jan 2024 23:47:02 +0100 Subject: [PATCH 037/152] viewer: use sign icons instead of default markers --- viewer/MinedMap.js | 51 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 03c3649..c9ae2d3 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -17,6 +17,44 @@ function contains(array, elem) { return false; } +const signKinds = { + sign: { + iconSize: [26, 28], + popupAnchor: [0, -20], + }, + wall_sign: { + iconSize: [26, 18], + popupAnchor: [0, -15], + }, + hanging_sign: { + iconSize: [28, 24], + popupAnchor: [0, -18], + }, + hanging_wall_sign: { + iconSize: [28, 28], + popupAnchor: [0, -20], + }, +} + +const signIcons = {}; + +function signIcon(material, kind) { + function createSignIcon(material, kind) { + const params = signKinds[kind]; + + return L.icon({ + iconUrl: `images/icon/${material}_${kind}.png`, + iconSize: params.iconSize, + popupAnchor: params.popupAnchor, + className: 'overzoomed', + }); + } + + + let icons = signIcons[material] ??= {}; + return icons[kind] ??= createSignIcon(material, kind); +} + const MinedMapLayer = L.TileLayer.extend({ initialize: function (mipmaps, layer) { L.TileLayer.prototype.initialize.call(this, '', { @@ -167,6 +205,9 @@ function loadSigns(signLayer) { const el = document.createElement('span'); const [x, z] = key.split(',').map((i) => +i); + let material = 'oak'; /* Default material */ + let kind = 'sign'; + group.forEach((sign) => { if (sign.front_text) { for (const line of sign.front_text) { @@ -185,13 +226,21 @@ function loadSigns(signLayer) { el.appendChild(document.createElement('hr')); } + + if (sign.material) + material = sign.material; + if (sign.kind) + kind = sign.kind; }); const lastChild = el.lastChild; if (lastChild) lastChild.remove(); - L.marker([-z-0.5, x+0.5]).addTo(signLayer).bindPopup(el); + L.marker([-z-0.5, x+0.5], { + icon: signIcon(material, kind), + + }).addTo(signLayer).bindPopup(el); } } From ac0fd06b169b9356da0317c7a50943f3a3964b83 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 01:56:03 +0100 Subject: [PATCH 038/152] viewer: add icon shadows --- viewer/MinedMap.js | 8 +++++--- viewer/images/icon/shadow_hanging_sign.png | Bin 0 -> 213 bytes viewer/images/icon/shadow_hanging_wall_sign.png | Bin 0 -> 200 bytes viewer/images/icon/shadow_sign.png | Bin 0 -> 194 bytes viewer/images/icon/shadow_wall_sign.png | Bin 0 -> 152 bytes 5 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 viewer/images/icon/shadow_hanging_sign.png create mode 100644 viewer/images/icon/shadow_hanging_wall_sign.png create mode 100644 viewer/images/icon/shadow_sign.png create mode 100644 viewer/images/icon/shadow_wall_sign.png diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index c9ae2d3..e4c8203 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -40,12 +40,14 @@ const signIcons = {}; function signIcon(material, kind) { function createSignIcon(material, kind) { - const params = signKinds[kind]; + const {iconSize, popupAnchor} = signKinds[kind]; return L.icon({ iconUrl: `images/icon/${material}_${kind}.png`, - iconSize: params.iconSize, - popupAnchor: params.popupAnchor, + iconSize, + popupAnchor, + shadowUrl: `images/icon/shadow_${kind}.png`, + shadowSize: [iconSize[0]+8, iconSize[1]+8], className: 'overzoomed', }); } diff --git a/viewer/images/icon/shadow_hanging_sign.png b/viewer/images/icon/shadow_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..dbd19a61cfc2912c0444f322b9891d69233e0bd8 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!3HFy+4N(86lZ})WHAE+w=f7ZGR&GI0TgWa zba4!^IQ@3AB42|6kE?u6R+SXDn8|m0=5~oPsml{DF)%hYtNBj<_jax5{f)gGCJyW@ zFQ0NtopZ2SFkPzAORrs6m$`yDt1|)xq*H*w(|0w@2lM~wKefaPBAI-ieQM`{c%6B)z$pk6QmJIiGKqoPHy85}S Ib4q9e0I7yV82|tP literal 0 HcmV?d00001 diff --git a/viewer/images/icon/shadow_hanging_wall_sign.png b/viewer/images/icon/shadow_hanging_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..771cef5bf4605223e1160b1f6ca9f614f555258d GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|&H|6fVg?3oVGw3ym^DWNC|Kp` z;uvCa`t1}$z6J#z*ZHTOypeq(aId~3?b_Bm2bW5yOgwUGnZ2T_L%h?^rOeB6B2*eI zSkE+=H!(RdRVExwj++mcxArxtOxVLPcfH$DCe!Gc uqFJK9*=wbq7`3xK7FSZ`cq{GQUBD2$NKQZBYK|_@6%3xPelF{r5}E)qaYkDJ literal 0 HcmV?d00001 diff --git a/viewer/images/icon/shadow_sign.png b/viewer/images/icon/shadow_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..9bf1cde2756964c656657607876999f26bbadbaf GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^fTV z)5S5w;`G}o2RRQY@VLfzE0?rewLC8G*x`I{r8<6y`Y?T61oCO|{#S9GG!XV7ZFl&wkP|(ZM z#W6(Vd~!-cf`H?pB~9i$JUsak3uaxFl#nnvVeo{F83@h@@UpS7Nwa-A5Us|h)ez|1 twpUT-!jkG{pTFh_C;##4Je@eZoT0mlhrfHJ|16-X44$rjF6*2UngFtWD0Bb- literal 0 HcmV?d00001 From 31de0dc0bdff094cb237b068572eb2892bd5b9d8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 16:01:29 +0100 Subject: [PATCH 039/152] viewer: sign popup styling --- viewer/MinedMap.js | 110 +++++++++++++++++++++++++++++++++++---------- viewer/index.html | 46 ++++++++++++++++++- 2 files changed, 131 insertions(+), 25 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index e4c8203..47aefff 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -160,7 +160,6 @@ const colors = { function formatSignLine(line) { const el = document.createElement('span'); el.style.whiteSpace = 'pre'; - el.style.fontFamily = 'sans'; for (const span of line) { const child = document.createElement('span'); @@ -190,6 +189,86 @@ function formatSignLine(line) { return el; } +function createSign(sign, back) { + // standing signs + function px(base) { + const scale = 11; + return (base*scale)+'px'; + } + // hanging signs + function pxh(base) { + const scale = 16; + return (base*scale)+'px'; + } + + const sizes = { + sign: { + width: px(24), + height: px(12), + paddingTop: px(0), + paddingBottom: px(14), + }, + wall_sign: { + width: px(24), + height: px(12), + paddingTop: px(0), + paddingBottom: px(0), + }, + hanging_sign: { + width: pxh(16), + height: pxh(10), + paddingTop: pxh(4), + paddingBottom: pxh(0), + }, + hanging_wall_sign: { + width: pxh(16), + height: pxh(10), + paddingTop: pxh(6), + paddingBottom: pxh(0), + }, + }; + const size = sizes[sign.kind]; + + const wrapper = document.createElement('div'); + wrapper.classList = 'sign-wrapper'; + + const title = document.createElement('div'); + title.classList = 'sign-title' + title.textContent = `Sign at ${sign.x}/${sign.y}/${sign.z}`; + if (back) + title.textContent += ' (back)'; + title.textContent += ':'; + + wrapper.appendChild(title); + + const container = document.createElement('div'); + container.style.width = size.width; + container.style.height = size.height; + container.style.paddingTop = size.paddingTop; + container.style.paddingBottom = size.paddingBottom; + container.style.backgroundImage = `url(images/bg/${sign.material}_${sign.kind}.png)`; + container.classList = 'sign-container overzoomed'; + + const content = document.createElement('div'); + content.classList = 'sign-content'; + + let text = []; + if (!back && sign.front_text) + text = sign.front_text; + else if (back && sign.back_text) + text = sign.back_text; + + for (const line of text) { + content.appendChild(formatSignLine(line)); + content.appendChild(document.createElement('br')); + } + + container.appendChild(content); + wrapper.appendChild(container); + + return wrapper; +} + function loadSigns(signLayer) { const xhr = new XMLHttpRequest(); xhr.onload = function () { @@ -204,30 +283,16 @@ function loadSigns(signLayer) { } for (const [key, group] of Object.entries(groups)) { - const el = document.createElement('span'); - const [x, z] = key.split(',').map((i) => +i); + const popup = document.createElement('div'); let material = 'oak'; /* Default material */ let kind = 'sign'; group.forEach((sign) => { - if (sign.front_text) { - for (const line of sign.front_text) { - el.appendChild(formatSignLine(line)); - el.appendChild(document.createElement('br')); - } + popup.appendChild(createSign(sign, false)); - el.appendChild(document.createElement('hr')); - } - - if (sign.back_text) { - for (let line of sign.back_text) { - el.appendChild(formatSignLine(line)); - el.appendChild(document.createElement('br')); - } - - el.appendChild(document.createElement('hr')); - } + if (sign.back_text) + popup.appendChild(createSign(sign, true)); if (sign.material) material = sign.material; @@ -235,14 +300,11 @@ function loadSigns(signLayer) { kind = sign.kind; }); - const lastChild = el.lastChild; - if (lastChild) - lastChild.remove(); + const [x, z] = key.split(',').map((i) => +i); L.marker([-z-0.5, x+0.5], { icon: signIcon(material, kind), - - }).addTo(signLayer).bindPopup(el); + }).addTo(signLayer).bindPopup(popup); } } diff --git a/viewer/index.html b/viewer/index.html index 8327600..caf32a0 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -22,7 +22,19 @@ background: #333; } - img.overzoomed { + .leaflet-container a.leaflet-popup-close-button { + color: #ccc; + } + + .leaflet-container a.leaflet-popup-close-button:hover { + color: #fff; + } + + .leaflet-popup-content-wrapper, .leaflet-popup-tip { + background: rgba(64, 64, 64, 0.5); + } + + .overzoomed { image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; @@ -31,6 +43,38 @@ -ms-interpolation-mode: nearest-neighbor; } + .sign-wrapper { + padding: 0; + padding-left: 4px; + margin-bottom: 2em; + } + + .sign-wrapper:last-child { + margin-bottom: 0; + } + + .sign-title { + color: #fff; + font-weight: bold; + margin-bottom: 0.5em; + } + + .sign-container { + padding: 0; + background-size: cover; + display: flex; + align-items: center; + justify-content: center; + } + + .sign-content { + padding: 0; + font-size: 18px; + line-height: 1.5; + text-align: center; + font-family: sans; + } + span.obfuscated:hover { background-color: transparent !important; } From 76df56c9ce41376b999b1da6acb2b415751bb007 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 16:11:54 +0100 Subject: [PATCH 040/152] viewer: sort signs at the same x/z coordinates from top to bottom --- viewer/MinedMap.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 47aefff..c1fd1c4 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -279,26 +279,30 @@ function loadSigns(signLayer) { for (const sign of res.signs) { const key = `${sign.x},${sign.z}`; const group = groups[key] ??= []; - group[sign.y] = sign; + group.push(sign); } for (const [key, group] of Object.entries(groups)) { const popup = document.createElement('div'); - let material = 'oak'; /* Default material */ - let kind = 'sign'; + let material; + let kind; - group.forEach((sign) => { + // Sort from top to bottom + group.sort((a, b) => b.y - a.y); + + for (const sign of group) { popup.appendChild(createSign(sign, false)); if (sign.back_text) popup.appendChild(createSign(sign, true)); - if (sign.material) - material = sign.material; - if (sign.kind) - kind = sign.kind; - }); + material ??= sign.material; + kind ??= sign.kind; + } + + // Default material + material ??= 'oak'; const [x, z] = key.split(',').map((i) => +i); From 7b3ac8647ef3730b4a81cbf4b90b433937a6b7c8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 19:03:22 +0100 Subject: [PATCH 041/152] viewer: store URL paramters in a 'params' variable --- viewer/MinedMap.js | 54 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index c1fd1c4..882691f 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -36,6 +36,7 @@ const signKinds = { }, } +const params = {}; const signIcons = {}; function signIcon(material, kind) { @@ -323,30 +324,28 @@ window.createMap = function () { mipmaps = res.mipmaps, spawn = res.spawn; - let x, z, zoom, light, signs; - const updateParams = function () { const args = parseHash(); - zoom = parseInt(args['zoom']); - x = parseFloat(args['x']); - z = parseFloat(args['z']); - light = parseInt(args['light']); - signs = parseInt(args['signs'] ?? '1'); + params.zoom = parseInt(args['zoom']); + params.x = parseFloat(args['x']); + params.z = parseFloat(args['z']); + params.light = parseInt(args['light']); + params.signs = parseInt(args['signs'] ?? '1'); - if (isNaN(zoom)) - zoom = 0; - if (isNaN(x)) - x = spawn.x; - if (isNaN(z)) - z = spawn.z; + if (isNaN(params.zoom)) + params.zoom = 0; + if (isNaN(params.x)) + params.x = spawn.x; + if (isNaN(params.z)) + params.z = spawn.z; }; updateParams(); const map = L.map('map', { - center: [-z, x], - zoom: zoom, + center: [-params.z, params.x], + zoom: params.zoom, minZoom: -(mipmaps.length-1), maxZoom: 5, crs: L.CRS.Simple, @@ -364,9 +363,9 @@ window.createMap = function () { mapLayer.addTo(map); - if (light) + if (params.light) map.addLayer(lightLayer); - if (signs) + if (params.signs) map.addLayer(signLayer); const overlayMaps = { @@ -384,10 +383,10 @@ window.createMap = function () { }); const makeHash = function () { - let ret = '#x='+x+'&z='+z; + let ret = '#x='+params.x+'&z='+params.z; - if (zoom != 0) - ret += '&zoom='+zoom; + if (params.zoom != 0) + ret += '&zoom='+params.zoom; if (map.hasLayer(lightLayer)) ret += '&light=1'; @@ -407,10 +406,11 @@ window.createMap = function () { return; } - zoom = map.getZoom(); - center = map.getCenter(); - x = Math.round(center.lng); - z = Math.round(-center.lat); + const center = map.getCenter(); + + params.zoom = map.getZoom(); + params.x = Math.round(center.lng); + params.z = Math.round(-center.lat); updateHash(); } @@ -428,13 +428,13 @@ window.createMap = function () { updateParams(); - map.setView([-z, x], zoom); + map.setView([-params.z, params.x], params.zoom); - if (light) + if (params.light) map.addLayer(lightLayer); else map.removeLayer(lightLayer); - if (signs) + if (params.signs) map.addLayer(signLayer); else map.removeLayer(signLayer); From 7daddd6bbc4f685cc52af48bcfafdbea309b381b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 19:22:56 +0100 Subject: [PATCH 042/152] viewer: include open marker in URL Allow sharing URLs that reference a marker. --- viewer/MinedMap.js | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 882691f..7dda976 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -39,6 +39,8 @@ const signKinds = { const params = {}; const signIcons = {}; +let updateHash = () => {}; + function signIcon(material, kind) { function createSignIcon(material, kind) { const {iconSize, popupAnchor} = signKinds[kind]; @@ -284,7 +286,7 @@ function loadSigns(signLayer) { } for (const [key, group] of Object.entries(groups)) { - const popup = document.createElement('div'); + const el = document.createElement('div'); let material; let kind; @@ -293,10 +295,10 @@ function loadSigns(signLayer) { group.sort((a, b) => b.y - a.y); for (const sign of group) { - popup.appendChild(createSign(sign, false)); + el.appendChild(createSign(sign, false)); if (sign.back_text) - popup.appendChild(createSign(sign, true)); + el.appendChild(createSign(sign, true)); material ??= sign.material; kind ??= sign.kind; @@ -307,9 +309,23 @@ function loadSigns(signLayer) { const [x, z] = key.split(',').map((i) => +i); - L.marker([-z-0.5, x+0.5], { + const popup = L.popup().setContent(el); + + popup.on('add', () => { + params.marker = [x, z]; + updateHash(); + }); + popup.on('remove', () => { + params.marker = null; + updateHash(); + }); + + const marker = L.marker([-z-0.5, x+0.5], { icon: signIcon(material, kind), }).addTo(signLayer).bindPopup(popup); + + if (params.marker && x === params.marker[0] && z === params.marker[1]) + marker.openPopup(); } } @@ -332,6 +348,7 @@ window.createMap = function () { params.z = parseFloat(args['z']); params.light = parseInt(args['light']); params.signs = parseInt(args['signs'] ?? '1'); + params.marker = (args['marker'] ?? '').split(',').map((i) => +i); if (isNaN(params.zoom)) params.zoom = 0; @@ -339,6 +356,8 @@ window.createMap = function () { params.x = spawn.x; if (isNaN(params.z)) params.z = spawn.z; + if (isNaN(params.marker[0]) || isNaN(params.marker[1])) + params.marker = null; }; updateParams(); @@ -392,11 +411,14 @@ window.createMap = function () { ret += '&light=1'; if (!map.hasLayer(signLayer)) ret += '&signs=0'; + if (params.marker) { + ret += `&marker=${params.marker[0]},${params.marker[1]}`; + } return ret; }; - const updateHash = function () { + updateHash = function () { window.location.hash = makeHash(); }; From 625f2a13a3028cc6cec21d964a409bd715e1f635 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 20:05:39 +0100 Subject: [PATCH 043/152] core/metadata_writer: add enabled features to metadata Only consider sign support enabled when at least one pattern is configured. --- src/core/metadata_writer.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index 03aac70..b051b69 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -44,6 +44,13 @@ struct Spawn { z: i32, } +/// Keeps track of enabled MinedMap features +#[derive(Debug, Serialize)] +struct Features { + /// Sign layer + signs: bool, +} + /// Viewer metadata JSON data structure #[derive(Debug, Serialize)] struct Metadata<'t> { @@ -51,6 +58,8 @@ struct Metadata<'t> { mipmaps: Vec>, /// Initial spawn point for new players spawn: Spawn, + /// Enabled MinedMap features + features: Features, } /// Viewer entity JSON data structure @@ -159,9 +168,14 @@ impl<'a> MetadataWriter<'a> { pub fn run(self) -> Result<()> { let level_dat = self.read_level_dat()?; + let features = Features { + signs: !self.config.sign_patterns.is_empty(), + }; + let mut metadata = Metadata { mipmaps: Vec::new(), spawn: Self::spawn(&level_dat), + features, }; for tile_map in self.tiles.iter() { From 08f84fa339066c56b61f734e119f99c9fd4bc1b6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 20:14:00 +0100 Subject: [PATCH 044/152] viewer: do not show sign layer when the feature is disabled --- viewer/MinedMap.js | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 7dda976..f32485e 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -338,7 +338,8 @@ window.createMap = function () { xhr.onload = function () { const res = JSON.parse(this.responseText), mipmaps = res.mipmaps, - spawn = res.spawn; + spawn = res.spawn, + features = res.features || {}; const updateParams = function () { const args = parseHash(); @@ -356,7 +357,7 @@ window.createMap = function () { params.x = spawn.x; if (isNaN(params.z)) params.z = spawn.z; - if (isNaN(params.marker[0]) || isNaN(params.marker[1])) + if (!features.signs || isNaN(params.marker[0]) || isNaN(params.marker[1])) params.marker = null; }; @@ -374,23 +375,25 @@ window.createMap = function () { ], }); + const overlayMaps = {}; + const mapLayer = new MinedMapLayer(mipmaps, 'map'); - const lightLayer = new MinedMapLayer(mipmaps, 'light'); - const signLayer = L.layerGroup(); - - loadSigns(signLayer); - mapLayer.addTo(map); + const lightLayer = new MinedMapLayer(mipmaps, 'light'); + overlayMaps['Illumination'] = lightLayer; if (params.light) map.addLayer(lightLayer); - if (params.signs) - map.addLayer(signLayer); - const overlayMaps = { - "Illumination": lightLayer, - "Signs": signLayer, - }; + let signLayer; + if (features.signs) { + signLayer = L.layerGroup(); + loadSigns(signLayer); + if (params.signs) + map.addLayer(signLayer); + + overlayMaps['Signs'] = signLayer; + } L.control.layers({}, overlayMaps).addTo(map); @@ -409,7 +412,7 @@ window.createMap = function () { if (map.hasLayer(lightLayer)) ret += '&light=1'; - if (!map.hasLayer(signLayer)) + if (features.signs && !map.hasLayer(signLayer)) ret += '&signs=0'; if (params.marker) { ret += `&marker=${params.marker[0]},${params.marker[1]}`; @@ -456,10 +459,12 @@ window.createMap = function () { map.addLayer(lightLayer); else map.removeLayer(lightLayer); - if (params.signs) - map.addLayer(signLayer); - else - map.removeLayer(signLayer); + if (features.signs) { + if (params.signs) + map.addLayer(signLayer); + else + map.removeLayer(signLayer); + } updateHash(); }; From 3d024c6cd884ac22c9e5ddc92778c0deecce8413 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 20:32:56 +0100 Subject: [PATCH 045/152] viewer: update opened marker popup on URL hash change --- viewer/MinedMap.js | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index f32485e..3abcaf6 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -38,9 +38,21 @@ const signKinds = { const params = {}; const signIcons = {}; +const markers = {}; let updateHash = () => {}; +function coordKey(coords) { + if (!coords) + return null; + + return `${coords[0]},${coords[1]}`; +} + +function getMarker(coords) { + return markers[coordKey(coords)]; +} + function signIcon(material, kind) { function createSignIcon(material, kind) { const {iconSize, popupAnchor} = signKinds[kind]; @@ -280,7 +292,7 @@ function loadSigns(signLayer) { // Group signs by x,z coordinates for (const sign of res.signs) { - const key = `${sign.x},${sign.z}`; + const key = coordKey([sign.x, sign.z]); const group = groups[key] ??= []; group.push(sign); } @@ -324,6 +336,8 @@ function loadSigns(signLayer) { icon: signIcon(material, kind), }).addTo(signLayer).bindPopup(popup); + markers[coordKey([x, z])] = marker; + if (params.marker && x === params.marker[0] && z === params.marker[1]) marker.openPopup(); } @@ -451,21 +465,27 @@ window.createMap = function () { if (window.location.hash === makeHash()) return; - updateParams(); + const prevMarkerCoords = params.marker; - map.setView([-params.z, params.x], params.zoom); + updateParams(); if (params.light) map.addLayer(lightLayer); else map.removeLayer(lightLayer); + if (features.signs) { if (params.signs) map.addLayer(signLayer); else map.removeLayer(signLayer); + + if (coordKey(prevMarkerCoords) !== coordKey(params.marker)) + getMarker(params.marker)?.openPopup(); } + map.setView([-params.z, params.x], params.zoom); + updateHash(); }; From 643035eaed96dfa5e99badba8dff02ab557bd207 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 Jan 2024 20:49:36 +0100 Subject: [PATCH 046/152] viewer: switch to modern fetch API, do not cache metadata and entity files --- viewer/MinedMap.js | 126 +++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 67 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 3abcaf6..e784eec 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -284,76 +284,71 @@ function createSign(sign, back) { return wrapper; } -function loadSigns(signLayer) { - const xhr = new XMLHttpRequest(); - xhr.onload = function () { - const res = JSON.parse(this.responseText); - const groups = {}; +async function loadSigns(signLayer) { + const response = await fetch('data/entities.json', {cache: 'no-store'}); + const res = await response.json(); - // Group signs by x,z coordinates - for (const sign of res.signs) { - const key = coordKey([sign.x, sign.z]); - const group = groups[key] ??= []; - group.push(sign); - } + const groups = {}; - for (const [key, group] of Object.entries(groups)) { - const el = document.createElement('div'); - - let material; - let kind; - - // Sort from top to bottom - group.sort((a, b) => b.y - a.y); - - for (const sign of group) { - el.appendChild(createSign(sign, false)); - - if (sign.back_text) - el.appendChild(createSign(sign, true)); - - material ??= sign.material; - kind ??= sign.kind; - } - - // Default material - material ??= 'oak'; - - const [x, z] = key.split(',').map((i) => +i); - - const popup = L.popup().setContent(el); - - popup.on('add', () => { - params.marker = [x, z]; - updateHash(); - }); - popup.on('remove', () => { - params.marker = null; - updateHash(); - }); - - const marker = L.marker([-z-0.5, x+0.5], { - icon: signIcon(material, kind), - }).addTo(signLayer).bindPopup(popup); - - markers[coordKey([x, z])] = marker; - - if (params.marker && x === params.marker[0] && z === params.marker[1]) - marker.openPopup(); - } + // Group signs by x,z coordinates + for (const sign of res.signs) { + const key = coordKey([sign.x, sign.z]); + const group = groups[key] ??= []; + group.push(sign); } - xhr.open('GET', 'data/entities.json', true); - xhr.send(); + for (const [key, group] of Object.entries(groups)) { + const el = document.createElement('div'); + + let material; + let kind; + + // Sort from top to bottom + group.sort((a, b) => b.y - a.y); + + for (const sign of group) { + el.appendChild(createSign(sign, false)); + + if (sign.back_text) + el.appendChild(createSign(sign, true)); + + material ??= sign.material; + kind ??= sign.kind; + } + + // Default material + material ??= 'oak'; + + const [x, z] = key.split(',').map((i) => +i); + + const popup = L.popup().setContent(el); + + popup.on('add', () => { + params.marker = [x, z]; + updateHash(); + }); + popup.on('remove', () => { + params.marker = null; + updateHash(); + }); + + const marker = L.marker([-z-0.5, x+0.5], { + icon: signIcon(material, kind), + }).addTo(signLayer).bindPopup(popup); + + markers[coordKey([x, z])] = marker; + + if (params.marker && x === params.marker[0] && z === params.marker[1]) + marker.openPopup(); + } } window.createMap = function () { - const xhr = new XMLHttpRequest(); - xhr.onload = function () { - const res = JSON.parse(this.responseText), - mipmaps = res.mipmaps, - spawn = res.spawn, - features = res.features || {}; + (async function () { + const response = await fetch('data/info.json', {cache: 'no-store'}); + const res = await response.json(); + const {mipmaps, spawn} = res; + const features = res.features || {}; const updateParams = function () { const args = parseHash(); @@ -489,8 +484,5 @@ window.createMap = function () { updateHash(); }; - }; - - xhr.open('GET', 'data/info.json', true); - xhr.send(); + })(); } From 03521684b9851f1380470245b846fca981ede1a0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 Jan 2024 23:57:23 +0100 Subject: [PATCH 047/152] README.md: add description of sign feature --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index be09c47..824b670 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired ## How to use Minecraft stores its save data in a directory `~/.minecraft/saves` on Linux, -and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate minedmap +and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate MinedMap tile data from a save game called "World", use the a command like the following (replacing the first argument with the path to your save data; `viewer` refers to the directory where you unpacked the MinedMap viewer): @@ -47,6 +47,34 @@ This test server is very slow and cannot handle multiple requests concurrently, a proper webserver like [nginx](https://nginx.org/) or upload the viewer together with the generated map files to public webspace to make the map available to others. +### Signs + +![Sign screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/e5d9c813ba3118d04dc7e52e3dc6f48808a69120/docs/images/signs.png) + +MinedMap can display sign markers on the map, which will open a popup showing +the sign text when clicked. + +Generation of the sign layer is disabled by default. It can be enabled by passing +the `--sign-prefix` or `--sign-filter` options to MinedMap. The options allow +to configure which signs should be displayed, and they can be passed multiple +times to show every sign that matches at least one prefix or filter. + +`--sign-prefix` will make all signs visible the text of which starts with the +given prefix, so something like `--sign-prefix '[Map]'` would allow to put up +signs that start with "\[Map\]" in Minecraft to add markers to the map. An +empty prefix (`--sign-prefix ''`) can be used to make *all* signs visible on +the map. + +`--sign-filter` can be used for more advanced filters based on regular expressions. +`--sign-filter '\[Map\]'` would show all signs that contain "\[Map\]" +anywhere in their text, and `--sign-filter '.'` makes all non-empty signs (signs +containing at least one character) visible. See the documentation of the +[regex crate](https://docs.rs/regex) for more information on the supported syntax. + +All prefixes and filters are applied to the front and back text separately, but +both the front and the back text will be shown in the popup when one of them +matches. + ## Installation Binary builds of the map generator for Linux and Windows, as well as an archive From 6299c871a94a407382d4f17fa1eb23a15799dd4e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 11 Jan 2024 00:02:25 +0100 Subject: [PATCH 048/152] CHANGELOG.md: add sign layer --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fccf759..b702c8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added sign layer + + This feature is disabled by default. Use the `--sign-prefix` and `--sign-filter` options to + configure which signs to show on the map. + ### Changed - Without `--verbose`, only a single warning is printed at the end of From 05d8faeb5cfc249917d456089df581ed6779bfaf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 11 Jan 2024 12:39:53 +0100 Subject: [PATCH 049/152] resource: README.md: sign-related updates --- resource/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resource/README.md b/resource/README.md index 08857ad..65caa08 100644 --- a/resource/README.md +++ b/resource/README.md @@ -11,6 +11,7 @@ work. - `extract.py`: Takes the block type information from `blocks.json` and texture data from an unpacked Minecraft JAR, storing the result in `colors.json` - `generate.py`: Generates `block_types.rs` from `colors.json` +- `sign_textures.py`: Generates all needed sign graphics from Minecraft assets In addition to these scripts, the JSON processor *jq* is a useful tool to work with MinedMap's resource metadata. @@ -47,7 +48,8 @@ with MinedMap's resource metadata. If possible, the top texture of blocks should be used where different sides exist. Block types that should not be visible on the map are just set to - `null` in the JSON. + `null` in the JSON (or have a `null` `texture` field when other flags need + to be set, like for sign blocks). The `water`, `grass` and `foliage` flags control biome-dependent texture color modifiers. From e18761a3e410e72b65301701aa157104b2bf9dbd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 11 Jan 2024 12:42:25 +0100 Subject: [PATCH 050/152] resource: extract.py: pass directory of unpacked Minecraft JAR, not full path to assets Make the script easier to use, and more consistent with sign_textures.py. --- resource/README.md | 2 +- resource/extract.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resource/README.md b/resource/README.md index 65caa08..ab9d5ea 100644 --- a/resource/README.md +++ b/resource/README.md @@ -43,7 +43,7 @@ with MinedMap's resource metadata. 5. Edit `blocks.json` until the following command passes without errors: ```sh - ./extract.py blocks.json data/new/assets/minecraft/textures/block colors.json + ./extract.py blocks.json data/new colors.json ``` If possible, the top texture of blocks should be used where different sides diff --git a/resource/extract.py b/resource/extract.py index 9621b95..31c1e97 100755 --- a/resource/extract.py +++ b/resource/extract.py @@ -11,7 +11,7 @@ if len(sys.argv) != 4: sys.exit('Usage: extract.py ') def mean_color(texture): - path = os.path.join(sys.argv[2], texture + '.png') + path = os.path.join(sys.argv[2], 'assets/minecraft/textures/block', texture + '.png') im = Image.open(path) data = im.convert('RGBA').getdata() From a99a734df89c22d176698115508c5db4e3ec8c95 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 25 Jan 2024 19:44:37 +0100 Subject: [PATCH 051/152] Update dependencies --- Cargo.lock | 90 +++++++++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e50f306..55deb2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,9 +46,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -136,15 +136,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "ed2490600f404f2b94c167e31d3ed1d5f3c225a0f3b80230053b3e0b7b962bd9" [[package]] name = "byteorder" @@ -176,9 +176,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.14" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.14" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -432,20 +432,19 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", "color_quant", - "num-rational", "num-traits", "png", ] @@ -499,9 +498,9 @@ checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libz-ng-sys" -version = "1.1.14" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81157dde2fd4ad2b45ea3a4bb47b8193b52a6346b678840d91d80d3c2cd166c5" +checksum = "c6409efc61b12687963e602df8ecf70e8ddacf95bc6576bcf16e3ac6328083c5" dependencies = [ "cmake", "libc", @@ -509,9 +508,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -633,17 +632,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.17" @@ -721,15 +709,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "png" -version = "0.17.10" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -740,9 +728,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -758,9 +746,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -768,9 +756,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -787,9 +775,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -799,9 +787,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -828,11 +816,11 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -917,9 +905,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "strsim" From 8a1a26c13c93c6ea48d4c7ade4e0bcbd087b074a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Jan 2024 22:34:41 +0100 Subject: [PATCH 052/152] core: add support for sign text transformations Add support for regexp replacement patterns, which can be useful when the text matched by --sign-filter or --sign-prefix should not be displayed. --- README.md | 6 ++++++ src/core/common.rs | 30 +++++++++++++++++++++++++++++- src/core/metadata_writer.rs | 31 ++++++++++++++++++++++++++++++- src/core/mod.rs | 6 ++++++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 824b670..b857454 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,12 @@ All prefixes and filters are applied to the front and back text separately, but both the front and the back text will be shown in the popup when one of them matches. +Finally, `--sign-transform` allows to specify sed-style replacement patterns to +modify the text displayed on the map. This can be used if the text matched by +`--sign-prefix` or `--sign-filter` should not be displayed: +`--sign-filter 's/\[Map\]//'` would replace each occurence of "\[Map\]" with +the empty string. + ## Installation Binary builds of the map generator for Linux and Windows, as well as an archive diff --git a/src/core/common.rs b/src/core/common.rs index 92d0019..9a94496 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -8,7 +8,7 @@ use std::{ use anyhow::{Context, Result}; use indexmap::IndexSet; -use regex::RegexSet; +use regex::{Regex, RegexSet}; use serde::{Deserialize, Serialize}; use crate::{ @@ -130,6 +130,7 @@ pub enum TileKind { } /// Common configuration based on command line arguments +#[derive(Debug)] pub struct Config { /// Number of threads for parallel processing pub num_threads: usize, @@ -151,6 +152,8 @@ pub struct Config { pub viewer_entities_path: PathBuf, /// Sign text filter patterns pub sign_patterns: RegexSet, + /// Sign text transformation pattern + pub sign_transforms: Vec<(Regex, String)>, } impl Config { @@ -173,6 +176,8 @@ impl Config { .collect(); let sign_patterns = Self::sign_patterns(args).context("Failed to parse sign patterns")?; + let sign_transforms = + Self::sign_transforms(args).context("Failed to parse sign transforms")?; Ok(Config { num_threads, @@ -185,6 +190,7 @@ impl Config { viewer_info_path, viewer_entities_path, sign_patterns, + sign_transforms, }) } @@ -200,6 +206,28 @@ impl Config { )?) } + /// Parses the sign transform argument into a vector of [Regex] and + /// corresponding replacement strings + fn sign_transforms(args: &super::Args) -> Result> { + let splitter = Regex::new(r"^s/((?:[^\\/]|\\.)*)/((?:[^\\/]|\\.)*)/$").unwrap(); + + args.sign_transform + .iter() + .map(|t| Self::sign_transform(&splitter, t)) + .collect() + } + + /// Parses the sign transform argument into a [Regex] and its corresponding + /// replacement string + fn sign_transform(splitter: &Regex, transform: &str) -> Result<(Regex, String)> { + let captures = splitter + .captures(transform) + .with_context(|| format!("Invalid transform pattern '{}'", transform))?; + let regexp = Regex::new(&captures[1])?; + let replacement = captures[2].to_string(); + Ok((regexp, replacement)) + } + /// Constructs the path to an input region file pub fn region_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "mca"); diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index b051b69..0ea1f65 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -1,6 +1,7 @@ //! The [MetadataWriter] and related types use anyhow::{Context, Result}; +use regex::Regex; use serde::Serialize; use crate::{ @@ -8,7 +9,7 @@ use crate::{ io::{fs, storage}, world::{ block_entity::{self, BlockEntity, BlockEntityData}, - de, + de, sign, }, }; @@ -145,6 +146,28 @@ impl<'a> MetadataWriter<'a> { false } + /// Applies a single transform to a [sign::SignText] + /// + /// The regular expression is applied for each line of the sign text + /// separately (actually for each element when JSON text is used) + fn sign_text_transform(sign_text: &mut sign::SignText, transform: &(Regex, String)) { + let (regexp, replacement) = transform; + + for line in &mut sign_text.0 { + for text in &mut line.0 { + text.text = regexp.replace_all(&text.text, replacement).into_owned() + } + } + } + + /// Applies the configured transforms to the text of a sign + fn sign_transform(&self, sign: &mut block_entity::Sign) { + for transform in &self.config.sign_transforms { + Self::sign_text_transform(&mut sign.front_text, transform); + Self::sign_text_transform(&mut sign.back_text, transform); + } + } + /// Generates [Entities] data from collected entity lists fn entities(&self) -> Result { let data: ProcessedEntities = @@ -158,6 +181,12 @@ impl<'a> MetadataWriter<'a> { .filter(|entity| match &entity.data { BlockEntityData::Sign(sign) => self.sign_filter(sign), }) + .map(|mut entity| { + match &mut entity.data { + BlockEntityData::Sign(sign) => self.sign_transform(sign), + }; + entity + }) .collect(), }; diff --git a/src/core/mod.rs b/src/core/mod.rs index 274bae8..f552ffa 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -59,6 +59,12 @@ pub struct Args { /// To make all signs visible, pass an empty string to either option. #[arg(long)] pub sign_filter: Vec, + /// Regular expression replacement pattern for sign texts + /// + /// Accepts patterns of the form 's/regexp/replacement/'. Transforms + /// are applied to each line of sign texts separately. + #[arg(long)] + pub sign_transform: Vec, /// Minecraft save directory pub input_dir: PathBuf, /// MinedMap data directory From 3d84e9c9e465ffece461ed6670d2e1aecb15bbd1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jan 2024 14:08:42 +0100 Subject: [PATCH 053/152] CHANGELOG.md: mention --sign-transform --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b702c8c..1e5f4b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ - Added sign layer This feature is disabled by default. Use the `--sign-prefix` and `--sign-filter` options to - configure which signs to show on the map. + configure which signs to show on the map. `--sign-transform` allows to modify the displayed + sign text. ### Changed From f186681b416f7ef24d329875723d0524dbd7afb3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jan 2024 14:14:48 +0100 Subject: [PATCH 054/152] release: move commit message configuration to workspace --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5442162..6654e5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/neocturne/MinedMap" [workspace.metadata.release] consolidate-commits = false +pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" @@ -26,7 +27,6 @@ exclude = [ ] [package.metadata.release] -pre-release-commit-message = "{{crate_name}} {{version}}" tag-message = "{{crate_name}} {{version}}" pre-release-replacements = [ {file="CHANGELOG.md", search="Unreleased", replace="{{version}}"}, From d6716a598badf82d6d73ca017ffbe1eb26592a54 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jan 2024 14:15:28 +0100 Subject: [PATCH 055/152] minedmap-resource 0.3.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55deb2d..f32b324 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -587,7 +587,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.2.0" +version = "0.3.0" dependencies = [ "enumflags2", "glam", diff --git a/Cargo.toml b/Cargo.toml index 6654e5c..e6a5113 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.2.0", path = "crates/resource" } +minedmap-resource = { version = "0.3.0", path = "crates/resource" } minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 5bed687..364ac85 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.2.0" +version = "0.3.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From 9fd3989a95fa6d446c9a36398b1996e99d7cb4e7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jan 2024 14:16:03 +0100 Subject: [PATCH 056/152] minedmap 2.1.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e5f4b4..b3b134e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.1.0] - 2024-01-27 + ### Added - Added sign layer @@ -74,7 +76,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.0.2...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.1.0...HEAD +[2.1.0]: https://github.com/neocturne/MinedMap/compare/v2.0.2...v2.1.0 [2.0.2]: https://github.com/neocturne/MinedMap/compare/v2.0.1...v2.0.2 [2.0.1]: https://github.com/neocturne/MinedMap/compare/v2.0.0...v2.0.1 [2.0.0]: https://github.com/neocturne/MinedMap/compare/v1.19.1...v2.0.0 diff --git a/Cargo.lock b/Cargo.lock index f32b324..2a88179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -545,7 +545,7 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "minedmap" -version = "2.0.2" +version = "2.1.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index e6a5113..082c5b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.0.2" +version = "2.1.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From 00eea4537501b1679873900d6470c7d8df0ed631 Mon Sep 17 00:00:00 2001 From: Myrddin Emrys Date: Wed, 14 Feb 2024 18:01:25 -0600 Subject: [PATCH 057/152] Improve README.md instructions. Added instructions that would have made my initial attempts to use the tool less confusing. --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b857454..402c7b2 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,18 @@ based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired ## How to use +Download both the release that matches your platform, as well as the platform- +independant viewer archive. Extract the viewer archive. This directory will be made +publicly accessible on a web server and will contain both the html and javascript to +operate the viewer, as well as the image data generated by MinedMap. + Minecraft stores its save data in a directory `~/.minecraft/saves` on Linux, and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate MinedMap tile data from a save game called "World", use the a command like the following -(replacing the first argument with the path to your save data; `viewer` refers +(replacing the first argument with the path to your save data; `` refers to the directory where you unpacked the MinedMap viewer): ```shell -minedmap ~/.minecraft/saves/World viewer/data +minedmap ~/.minecraft/saves/World /data ``` The first map generation might take a while for big worlds, but subsequent calls will @@ -47,6 +52,10 @@ This test server is very slow and cannot handle multiple requests concurrently, a proper webserver like [nginx](https://nginx.org/) or upload the viewer together with the generated map files to public webspace to make the map available to others. +If you are uploading the directory to a remote webserver, you do not need to upload the +`/data/processed` directory, as that is only used locally to make updates +process more quickly. + ### Signs ![Sign screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/e5d9c813ba3118d04dc7e52e3dc6f48808a69120/docs/images/signs.png) From bccd6d6cb4fad4a7d6bd8a7d3669ac4706428d6d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 Mar 2024 23:43:42 +0100 Subject: [PATCH 058/152] README.md: some rewording --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 402c7b2..8f7867f 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,12 @@ based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired ## How to use -Download both the release that matches your platform, as well as the platform- -independant viewer archive. Extract the viewer archive. This directory will be made -publicly accessible on a web server and will contain both the html and javascript to -operate the viewer, as well as the image data generated by MinedMap. +Download the binary release that matches your platform from the Github release +page (or install from source using `cargo`), as well as the platform-independent +viewer archive. Extract the viewer archive. The extracted directory contains the +HTML and JavaScript to operate the viewer and will be made publicly accessible +on a web server. The image data generated by MinedMap will be stored in the +`data` subdirectory of the extracted viewer. Minecraft stores its save data in a directory `~/.minecraft/saves` on Linux, and `C:\Users\\AppData\Roaming\.minecraft\saves`. To generate MinedMap @@ -52,9 +54,9 @@ This test server is very slow and cannot handle multiple requests concurrently, a proper webserver like [nginx](https://nginx.org/) or upload the viewer together with the generated map files to public webspace to make the map available to others. -If you are uploading the directory to a remote webserver, you do not need to upload the -`/data/processed` directory, as that is only used locally to make updates -process more quickly. +If you are uploading the directory to a remote webserver, you do not need to upload the +`/data/processed` directory, as that is only used locally to allow processing +updates more quickly. ### Signs From 44e914599b1d6a2ab43fc32a960fa0a5e9b0b028 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 Mar 2024 23:48:49 +0100 Subject: [PATCH 059/152] types: fix new clippy lint --- crates/types/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index e219a97..b4f12c2 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -47,8 +47,7 @@ macro_rules! coord_type { /// Returns an iterator over all possible values of the type #[inline] - pub fn iter() -> impl Iterator> - + DoubleEndedIterator + pub fn iter() -> impl DoubleEndedIterator> + ExactSizeIterator + FusedIterator + Clone From 39b073f24b8837cec00f4b554271930a6bbd2a04 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 Mar 2024 23:48:42 +0100 Subject: [PATCH 060/152] Update dependencies --- Cargo.lock | 197 ++++++++++++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a88179..b87c678 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -46,9 +46,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -60,9 +60,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -94,9 +94,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "autocfg" @@ -142,9 +142,9 @@ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bytemuck" -version = "1.14.1" +version = "1.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2490600f404f2b94c167e31d3ed1d5f3c225a0f3b80230053b3e0b7b962bd9" +checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" [[package]] name = "byteorder" @@ -176,9 +176,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -211,9 +211,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "cmake" @@ -238,9 +238,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -272,15 +272,15 @@ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "enumflags2" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" dependencies = [ "enumflags2_derive", "serde", @@ -288,9 +288,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", @@ -315,9 +315,9 @@ dependencies = [ [[package]] name = "fastnbt" -version = "2.4.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369bd70629bccfda7e344883c9ae3ab7f3b10a357bcf8b0f69caa7256bcf188" +checksum = "7d4a73a95dc65551ccd98e1ecd1adb5d1ba5361146963b31f481ca42fc0520a3" dependencies = [ "byteorder", "cesu8", @@ -432,15 +432,15 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "image" -version = "0.24.8" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", @@ -451,9 +451,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown", @@ -462,9 +462,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -477,9 +477,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] @@ -492,9 +492,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libz-ng-sys" @@ -524,15 +524,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ "hashbrown", ] @@ -604,9 +604,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", "simd-adler32", @@ -624,19 +624,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -709,15 +708,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "png" -version = "0.17.11" +version = "0.17.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -746,9 +745,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", @@ -816,9 +815,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.2", "errno", @@ -829,9 +828,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "scopeguard" @@ -841,9 +840,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -859,9 +858,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -870,9 +869,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -911,15 +910,15 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -938,9 +937,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -948,9 +947,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "parking_lot", @@ -1075,7 +1074,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -1095,17 +1094,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -1116,9 +1115,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -1128,9 +1127,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -1140,9 +1139,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -1152,9 +1151,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -1164,9 +1163,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -1176,9 +1175,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -1188,9 +1187,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "zerocopy" From 66189d279cd27c7df9f4fee8a5fa8e30fffd453e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Jun 2024 16:02:56 +0200 Subject: [PATCH 061/152] core: region_processor: fix crash due to incorrect counting in info message Fixes #52 --- CHANGELOG.md | 7 +++++ Cargo.lock | 21 +++++++++++++++ Cargo.toml | 1 + src/core/region_processor.rs | 52 +++++++++++++----------------------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b134e..efcf8d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] - ReleaseDate +### Fixed + +- Fix crash due to incorrect counting in info message + + The calculation of the number of skipped regions could underflow when more invalid than valid + regions were encountered. + ## [2.1.0] - 2024-01-27 ### Added diff --git a/Cargo.lock b/Cargo.lock index b87c678..1780b1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -276,6 +276,26 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enumflags2" version = "0.7.9" @@ -550,6 +570,7 @@ dependencies = [ "anyhow", "bincode", "clap", + "enum-map", "fastnbt", "futures-util", "git-version", diff --git a/Cargo.toml b/Cargo.toml index 082c5b6..f8bb35f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ pre-release-replacements = [ anyhow = "1.0.68" bincode = "1.3.3" clap = { version = "4.1.4", features = ["derive", "wrap_help"] } +enum-map = "2.7.3" fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 63d5c09..9778061 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,16 +1,9 @@ //! The [RegionProcessor] and related functions -use std::{ - ffi::OsStr, - path::PathBuf, - sync::{ - atomic::{AtomicBool, Ordering}, - mpsc, - }, - time::SystemTime, -}; +use std::{ffi::OsStr, path::PathBuf, sync::mpsc, time::SystemTime}; use anyhow::{Context, Result}; +use enum_map::{Enum, EnumMap}; use rayon::prelude::*; use tracing::{debug, info, warn}; @@ -36,7 +29,7 @@ fn parse_region_filename(file_name: &OsStr) -> Option { } /// [RegionProcessor::process_region] return values -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Enum)] enum RegionProcessorStatus { /// Region was processed Ok, @@ -363,6 +356,8 @@ impl<'a> RegionProcessor<'a> { /// /// Returns a list of the coordinates of all processed regions pub fn run(self) -> Result> { + use RegionProcessorStatus as Status; + fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; fs::create_dir_all(&self.config.entities_dir(0))?; @@ -370,31 +365,18 @@ impl<'a> RegionProcessor<'a> { info!("Processing region files..."); let (region_send, region_recv) = mpsc::channel(); - let (processed_send, processed_recv) = mpsc::channel(); - let (error_send, error_recv) = mpsc::channel(); - - let has_unknown = AtomicBool::new(false); + let (status_send, status_recv) = mpsc::channel(); self.collect_regions()?.par_iter().try_for_each(|&coords| { let ret = self .process_region(coords) .with_context(|| format!("Failed to process region {:?}", coords))?; - if ret != RegionProcessorStatus::ErrorMissing { + if ret != Status::ErrorMissing { region_send.send(coords).unwrap(); } - match ret { - RegionProcessorStatus::Ok => processed_send.send(()).unwrap(), - RegionProcessorStatus::OkWithUnknown => { - has_unknown.store(true, Ordering::Relaxed); - processed_send.send(()).unwrap(); - } - RegionProcessorStatus::Skipped => {} - RegionProcessorStatus::ErrorOk | RegionProcessorStatus::ErrorMissing => { - error_send.send(()).unwrap() - } - } + status_send.send(ret).unwrap(); anyhow::Ok(()) })?; @@ -402,19 +384,21 @@ impl<'a> RegionProcessor<'a> { drop(region_send); let mut regions: Vec<_> = region_recv.into_iter().collect(); - drop(processed_send); - let processed = processed_recv.into_iter().count(); - drop(error_send); - let errors = error_recv.into_iter().count(); + drop(status_send); + + let mut status = EnumMap::<_, usize>::default(); + for ret in status_recv { + status[ret] += 1; + } info!( "Processed region files ({} processed, {} unchanged, {} errors)", - processed, - regions.len() - processed - errors, - errors, + status[Status::Ok] + status[Status::OkWithUnknown], + status[Status::Skipped], + status[Status::ErrorOk] + status[Status::ErrorMissing], ); - if has_unknown.into_inner() { + if status[Status::OkWithUnknown] > 0 { warn!("Unknown block or biome types found during processing"); eprint!(concat!( "\n", From e74e7be68667f7562e57b1ed14bce25a796be336 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Jun 2024 16:15:56 +0200 Subject: [PATCH 062/152] core: region_processor: ignore empty region files Minecraft generates empty region files in some cases. Just ignore these files instead of printing an error message for each. --- CHANGELOG.md | 4 ++++ src/core/region_processor.rs | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efcf8d5..c010654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The calculation of the number of skipped regions could underflow when more invalid than valid regions were encountered. +- Ignore empty region files instead of treating them as invalid + + Minecraft generates empty region files in some cases. Just ignore them instead of printing an + error message every time. ## [2.1.0] - 2024-01-27 diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 9778061..ce2d060 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -337,11 +337,20 @@ impl<'a> RegionProcessor<'a> { })? .filter_map(|entry| entry.ok()) .filter(|entry| { - // We are only interested in regular files - matches!( - entry.file_type().map(|file_type| file_type.is_file()), - Ok(true) - ) + (|| { + // We are only interested in regular files + let file_type = entry.file_type().ok()?; + if !file_type.is_file() { + return None; + } + + let metadata = entry.metadata().ok()?; + if metadata.len() == 0 { + return None; + } + Some(()) + })() + .is_some() }) .filter_map(|entry| parse_region_filename(&entry.file_name())) .collect()) From e9abe6b502b0a77b2429e99f829c29ccb664edec Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Jun 2024 16:31:18 +0200 Subject: [PATCH 063/152] minedmap 2.1.1 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c010654..d877117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.1.1] - 2024-06-14 + ### Fixed - Fix crash due to incorrect counting in info message @@ -87,7 +89,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.1.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.1.1...HEAD +[2.1.1]: https://github.com/neocturne/MinedMap/compare/v2.1.0...v2.1.1 [2.1.0]: https://github.com/neocturne/MinedMap/compare/v2.0.2...v2.1.0 [2.0.2]: https://github.com/neocturne/MinedMap/compare/v2.0.1...v2.0.2 [2.0.1]: https://github.com/neocturne/MinedMap/compare/v2.0.0...v2.0.1 diff --git a/Cargo.lock b/Cargo.lock index 1780b1f..890b515 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -565,7 +565,7 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "minedmap" -version = "2.1.0" +version = "2.1.1" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index f8bb35f..ac9d456 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.1.0" +version = "2.1.1" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From 661da4698dfeab11cb5d57a17696b13886d2597c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 19 Jun 2024 19:38:52 +0200 Subject: [PATCH 064/152] workflows: update MacOS jobs to macos-13 --- .github/workflows/MinedMap.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index b09d620..c2e9961 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -91,9 +91,9 @@ jobs: fail-fast: false matrix: include: - - os: 'macos-11' + - os: 'macos-13' target: 'aarch64-apple-darwin' - - os: 'macos-11' + - os: 'macos-13' target: 'x86_64-apple-darwin' - os: 'windows-2019' target: 'x86_64-pc-windows-msvc' From bc8219772fc0ef0b69e4050ac6ff3988b1b2954e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Jun 2024 01:16:27 +0200 Subject: [PATCH 065/152] README.md: mention argument quoting difference on Windows --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 8f7867f..efa6573 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,11 @@ modify the text displayed on the map. This can be used if the text matched by `--sign-filter 's/\[Map\]//'` would replace each occurence of "\[Map\]" with the empty string. +**Note:** On Windows, double quotes (`"`) must be used for arguments instead +of single quotes (`'`), and all backslashes in the arguments must be escaped +by doubling them. This can make regular expressions somewhat difficult to +write and to read. + ## Installation Binary builds of the map generator for Linux and Windows, as well as an archive From 7f3e47fcb4b5f7a05c3bab878e0bc17e595b8894 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Jun 2024 01:17:33 +0200 Subject: [PATCH 066/152] treewide: update dependencies --- Cargo.lock | 358 +++++++++++++++++++------------------ Cargo.toml | 4 +- crates/resource/Cargo.toml | 2 +- crates/types/Cargo.toml | 2 +- 4 files changed, 187 insertions(+), 179 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 890b515..2ae562a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -31,62 +31,63 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -94,21 +95,21 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -136,15 +137,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "byteorder" @@ -154,12 +155,13 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -176,9 +178,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.1" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -186,9 +188,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", @@ -199,9 +201,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck", "proc-macro2", @@ -211,9 +213,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "cmake" @@ -224,23 +226,17 @@ dependencies = [ "cc", ] -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -266,15 +262,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "either" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "enum-map" @@ -298,9 +294,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -308,9 +304,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", @@ -325,9 +321,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -356,9 +352,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "libz-ng-sys", @@ -404,9 +400,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "git-version" @@ -430,15 +426,15 @@ dependencies = [ [[package]] name = "glam" -version = "0.25.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" +checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -446,9 +442,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -458,22 +454,21 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "image" -version = "0.24.9" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" dependencies = [ "bytemuck", "byteorder", - "color_quant", "num-traits", "png", ] [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -481,40 +476,46 @@ dependencies = [ ] [[package]] -name = "itertools" -version = "0.12.1" +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libz-ng-sys" @@ -528,15 +529,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -559,9 +560,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" @@ -625,9 +626,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "simd-adler32", @@ -654,9 +655,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -673,9 +674,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] @@ -694,9 +695,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -704,22 +705,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -748,27 +749,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -786,18 +787,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -807,9 +808,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -818,29 +819,29 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -849,9 +850,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "scopeguard" @@ -861,9 +862,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -879,9 +880,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -890,9 +891,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -925,21 +926,21 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.52" +version = "2.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" dependencies = [ "proc-macro2", "quote", @@ -968,9 +969,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.36.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "parking_lot", @@ -1042,9 +1043,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" @@ -1095,7 +1096,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1115,17 +1116,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -1136,9 +1138,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -1148,9 +1150,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -1160,9 +1162,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -1172,9 +1180,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -1184,9 +1192,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -1196,9 +1204,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -1208,24 +1216,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", @@ -1234,27 +1242,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index ac9d456..6fa4cdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ enum-map = "2.7.3" fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" -image = { version = "0.24.5", default-features = false, features = ["png"] } +image = { version = "0.25.1", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } @@ -54,7 +54,7 @@ num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" regex = "1.10.2" -rustc-hash = "1.1.0" +rustc-hash = "2.0.0" serde = { version = "1.0.152", features = ["rc", "derive"] } serde_json = "1.0.99" tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 364ac85..326e269 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -9,5 +9,5 @@ repository.workspace = true [dependencies] enumflags2 = { version = "0.7.7", features = ["serde"] } -glam = "0.25.0" +glam = "0.28.0" serde = { version = "1.0.183", features = ["derive"] } diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index e67d824..c294466 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -8,5 +8,5 @@ readme.workspace = true repository.workspace = true [dependencies] -itertools = "0.12.0" +itertools = "0.13.0" serde = { version = "1.0.183", features = ["derive"] } From 414ad5a49374f8a20fc53f3c24baf30dbf1171df Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 19 Jun 2024 19:15:20 +0200 Subject: [PATCH 067/152] resource: add Minecraft 1.21 block types --- CHANGELOG.md | 4 + README.md | 2 +- crates/resource/src/block_types.rs | 570 +++++++++++++++++++++++++++++ resource/blocks.json | 131 +++++++ src/core/common.rs | 4 +- 5 files changed, 708 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d877117..318ee9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added support for Minecraft 1.21 block types + ## [2.1.1] - 2024-06-14 ### Fixed diff --git a/README.md b/README.md index efa6573..9a07aed 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ * Render beautiful maps of your [Minecraft](https://minecraft.net/) worlds! * Put them on a webserver and view them in your browser! -* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.20 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21 (no mod installation necessary!) * Illumination layer: the world at night * Fast: create a full map for a huge 3GB savegame in less than 5 minutes in single-threaded operation * Multi-threading support: pass `-j N` to the renderer to use `N` parallel threads for generation diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 6229016..cbfe1b7 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -1843,6 +1843,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([184, 100, 73]), + }, + sign_material: None, + }, + ), ( "chiseled_deepslate", ConstBlockType { @@ -1913,6 +1923,26 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "chiseled_tuff", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([89, 94, 86]), + }, + sign_material: None, + }, + ), + ( + "chiseled_tuff_bricks", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 113, 106]), + }, + sign_material: None, + }, + ), ( "chorus_flower", ConstBlockType { @@ -2123,6 +2153,36 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([156, 86, 57]), + }, + sign_material: None, + }, + ), + ( + "copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 109, 82]), + }, + sign_material: None, + }, + ), + ( + "copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 107, 79]), + }, + sign_material: None, + }, + ), ( "copper_ore", ConstBlockType { @@ -2133,6 +2193,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 106, 79]), + }, + sign_material: None, + }, + ), ( "cornflower", ConstBlockType { @@ -2193,6 +2263,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "crafter", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([112, 98, 99]), + }, + sign_material: None, + }, + ), ( "crafting_table", ConstBlockType { @@ -3533,6 +3613,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "exposed_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 119, 100]), + }, + sign_material: None, + }, + ), ( "exposed_copper", ConstBlockType { @@ -3543,6 +3633,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "exposed_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 107, 89]), + }, + sign_material: None, + }, + ), + ( + "exposed_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([164, 123, 106]), + }, + sign_material: None, + }, + ), + ( + "exposed_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 104]), + }, + sign_material: None, + }, + ), + ( + "exposed_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 104]), + }, + sign_material: None, + }, + ), ( "exposed_cut_copper", ConstBlockType { @@ -4183,6 +4313,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "heavy_core", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 86, 94]), + }, + sign_material: None, + }, + ), ( "heavy_weighted_pressure_plate", ConstBlockType { @@ -6273,6 +6413,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "oxidized_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 161, 132]), + }, + sign_material: None, + }, + ), ( "oxidized_copper", ConstBlockType { @@ -6283,6 +6433,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "oxidized_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 132, 109]), + }, + sign_material: None, + }, + ), + ( + "oxidized_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 160, 132]), + }, + sign_material: None, + }, + ), + ( + "oxidized_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 161, 131]), + }, + sign_material: None, + }, + ), + ( + "oxidized_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 161, 132]), + }, + sign_material: None, + }, + ), ( "oxidized_cut_copper", ConstBlockType { @@ -6863,6 +7053,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "polished_tuff", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 104, 99]), + }, + sign_material: None, + }, + ), + ( + "polished_tuff_slab", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 104, 99]), + }, + sign_material: None, + }, + ), + ( + "polished_tuff_stairs", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 104, 99]), + }, + sign_material: None, + }, + ), + ( + "polished_tuff_wall", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([97, 104, 99]), + }, + sign_material: None, + }, + ), ( "poppy", ConstBlockType { @@ -9153,6 +9383,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "trial_spawner", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([56, 82, 98]), + }, + sign_material: None, + }, + ), ( "tripwire", ConstBlockType { @@ -9223,6 +9463,76 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "tuff_brick_slab", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 102, 95]), + }, + sign_material: None, + }, + ), + ( + "tuff_brick_stairs", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 102, 95]), + }, + sign_material: None, + }, + ), + ( + "tuff_brick_wall", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 102, 95]), + }, + sign_material: None, + }, + ), + ( + "tuff_bricks", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([98, 102, 95]), + }, + sign_material: None, + }, + ), + ( + "tuff_slab", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 109, 102]), + }, + sign_material: None, + }, + ), + ( + "tuff_stairs", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 109, 102]), + }, + sign_material: None, + }, + ), + ( + "tuff_wall", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 109, 102]), + }, + sign_material: None, + }, + ), ( "turtle_egg", ConstBlockType { @@ -9253,6 +9563,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "vault", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 69, 79]), + }, + sign_material: None, + }, + ), ( "verdant_froglight", ConstBlockType { @@ -9513,6 +9833,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([184, 100, 73]), + }, + sign_material: None, + }, + ), ( "waxed_copper_block", ConstBlockType { @@ -9523,6 +9853,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([156, 86, 57]), + }, + sign_material: None, + }, + ), + ( + "waxed_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([192, 109, 82]), + }, + sign_material: None, + }, + ), + ( + "waxed_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 107, 79]), + }, + sign_material: None, + }, + ), + ( + "waxed_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 106, 79]), + }, + sign_material: None, + }, + ), ( "waxed_cut_copper", ConstBlockType { @@ -9553,6 +9923,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_exposed_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([154, 119, 100]), + }, + sign_material: None, + }, + ), ( "waxed_exposed_copper", ConstBlockType { @@ -9563,6 +9943,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_exposed_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 107, 89]), + }, + sign_material: None, + }, + ), + ( + "waxed_exposed_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([164, 123, 106]), + }, + sign_material: None, + }, + ), + ( + "waxed_exposed_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 104]), + }, + sign_material: None, + }, + ), + ( + "waxed_exposed_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([161, 125, 104]), + }, + sign_material: None, + }, + ), ( "waxed_exposed_cut_copper", ConstBlockType { @@ -9593,6 +10013,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_oxidized_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 161, 132]), + }, + sign_material: None, + }, + ), ( "waxed_oxidized_copper", ConstBlockType { @@ -9603,6 +10033,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_oxidized_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([70, 132, 109]), + }, + sign_material: None, + }, + ), + ( + "waxed_oxidized_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 160, 132]), + }, + sign_material: None, + }, + ), + ( + "waxed_oxidized_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([82, 161, 131]), + }, + sign_material: None, + }, + ), + ( + "waxed_oxidized_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([83, 161, 132]), + }, + sign_material: None, + }, + ), ( "waxed_oxidized_cut_copper", ConstBlockType { @@ -9633,6 +10103,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_weathered_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 150, 111]), + }, + sign_material: None, + }, + ), ( "waxed_weathered_copper", ConstBlockType { @@ -9643,6 +10123,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "waxed_weathered_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 126, 99]), + }, + sign_material: None, + }, + ), + ( + "waxed_weathered_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 150, 109]), + }, + sign_material: None, + }, + ), + ( + "waxed_weathered_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 152, 110]), + }, + sign_material: None, + }, + ), + ( + "waxed_weathered_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, + sign_material: None, + }, + ), ( "waxed_weathered_cut_copper", ConstBlockType { @@ -9673,6 +10193,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "weathered_chiseled_copper", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([104, 150, 111]), + }, + sign_material: None, + }, + ), ( "weathered_copper", ConstBlockType { @@ -9683,6 +10213,46 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "weathered_copper_bulb", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([92, 126, 99]), + }, + sign_material: None, + }, + ), + ( + "weathered_copper_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([110, 150, 109]), + }, + sign_material: None, + }, + ), + ( + "weathered_copper_grate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 152, 110]), + }, + sign_material: None, + }, + ), + ( + "weathered_copper_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 153, 110]), + }, + sign_material: None, + }, + ), ( "weathered_cut_copper", ConstBlockType { diff --git a/resource/blocks.json b/resource/blocks.json index f8b0165..9d70f96 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -408,6 +408,7 @@ "chiseled_bookshelf": { "texture": "chiseled_bookshelf_top" }, + "chiseled_copper": {}, "chiseled_deepslate": {}, "chiseled_nether_bricks": {}, "chiseled_polished_blackstone": {}, @@ -419,6 +420,10 @@ "texture": "sandstone_top" }, "chiseled_stone_bricks": {}, + "chiseled_tuff": {}, + "chiseled_tuff_bricks": { + "texture": "chiseled_tuff_bricks_top" + }, "chorus_flower": {}, "chorus_plant": {}, "clay": {}, @@ -458,13 +463,22 @@ }, "conduit": {}, "copper_block": {}, + "copper_bulb": {}, + "copper_door": { + "texture": "copper_door_top" + }, + "copper_grate": {}, "copper_ore": {}, + "copper_trapdoor": {}, "cornflower": null, "cracked_deepslate_bricks": {}, "cracked_deepslate_tiles": {}, "cracked_nether_bricks": {}, "cracked_polished_blackstone_bricks": {}, "cracked_stone_bricks": {}, + "crafter": { + "texture": "crafter_top" + }, "crafting_table": { "texture": "crafting_table_top" }, @@ -733,7 +747,14 @@ "ender_chest": { "texture": "obsidian" }, + "exposed_chiseled_copper": {}, "exposed_copper": {}, + "exposed_copper_bulb": {}, + "exposed_copper_door": { + "texture": "exposed_copper_door_top" + }, + "exposed_copper_grate": {}, + "exposed_copper_trapdoor": {}, "exposed_cut_copper": {}, "exposed_cut_copper_slab": { "texture": "exposed_cut_copper" @@ -843,6 +864,7 @@ "hay_block": { "texture": "hay_block_top" }, + "heavy_core": {}, "heavy_weighted_pressure_plate": { "texture": "iron_block" }, @@ -1269,7 +1291,14 @@ "orange_wall_banner": null, "orange_wool": {}, "oxeye_daisy": null, + "oxidized_chiseled_copper": {}, "oxidized_copper": {}, + "oxidized_copper_bulb": {}, + "oxidized_copper_door": { + "texture": "oxidized_copper_door_top" + }, + "oxidized_copper_grate": {}, + "oxidized_copper_trapdoor": {}, "oxidized_cut_copper": {}, "oxidized_cut_copper_slab": { "texture": "oxidized_cut_copper" @@ -1390,6 +1419,16 @@ "polished_granite_stairs": { "texture": "polished_granite" }, + "polished_tuff": {}, + "polished_tuff_slab": { + "texture": "polished_tuff" + }, + "polished_tuff_stairs": { + "texture": "polished_tuff" + }, + "polished_tuff_wall": { + "texture": "polished_tuff" + }, "poppy": null, "potatoes": { "texture": "potatoes_stage3" @@ -1912,6 +1951,9 @@ "trapped_chest": { "texture": "oak_planks" }, + "trial_spawner": { + "texture": "trial_spawner_top_inactive" + }, "tripwire": null, "tripwire_hook": null, "tube_coral": null, @@ -1919,9 +1961,31 @@ "tube_coral_fan": null, "tube_coral_wall_fan": null, "tuff": {}, + "tuff_brick_slab": { + "texture": "tuff_bricks" + }, + "tuff_brick_stairs": { + "texture": "tuff_bricks" + }, + "tuff_brick_wall": { + "texture": "tuff_bricks" + }, + "tuff_bricks": {}, + "tuff_slab": { + "texture": "tuff" + }, + "tuff_stairs": { + "texture": "tuff" + }, + "tuff_wall": { + "texture": "tuff" + }, "turtle_egg": {}, "twisting_vines": {}, "twisting_vines_plant": {}, + "vault": { + "texture": "vault_top" + }, "verdant_froglight": { "texture": "verdant_froglight_top" }, @@ -1991,9 +2055,24 @@ "water_cauldron": { "texture": "cauldron_top" }, + "waxed_chiseled_copper": { + "texture": "chiseled_copper" + }, "waxed_copper_block": { "texture": "copper_block" }, + "waxed_copper_bulb": { + "texture": "copper_bulb" + }, + "waxed_copper_door": { + "texture": "copper_door_top" + }, + "waxed_copper_grate": { + "texture": "copper_grate" + }, + "waxed_copper_trapdoor": { + "texture": "copper_trapdoor" + }, "waxed_cut_copper": { "texture": "cut_copper" }, @@ -2003,9 +2082,24 @@ "waxed_cut_copper_stairs": { "texture": "cut_copper" }, + "waxed_exposed_chiseled_copper": { + "texture": "exposed_chiseled_copper" + }, "waxed_exposed_copper": { "texture": "exposed_copper" }, + "waxed_exposed_copper_bulb": { + "texture": "exposed_copper_bulb" + }, + "waxed_exposed_copper_door": { + "texture": "exposed_copper_door_top" + }, + "waxed_exposed_copper_grate": { + "texture": "exposed_copper_grate" + }, + "waxed_exposed_copper_trapdoor": { + "texture": "exposed_copper_trapdoor" + }, "waxed_exposed_cut_copper": { "texture": "exposed_cut_copper" }, @@ -2015,9 +2109,24 @@ "waxed_exposed_cut_copper_stairs": { "texture": "exposed_cut_copper" }, + "waxed_oxidized_chiseled_copper": { + "texture": "oxidized_chiseled_copper" + }, "waxed_oxidized_copper": { "texture": "oxidized_copper" }, + "waxed_oxidized_copper_bulb": { + "texture": "oxidized_copper_bulb" + }, + "waxed_oxidized_copper_door": { + "texture": "oxidized_copper_door_top" + }, + "waxed_oxidized_copper_grate": { + "texture": "oxidized_copper_grate" + }, + "waxed_oxidized_copper_trapdoor": { + "texture": "oxidized_copper_trapdoor" + }, "waxed_oxidized_cut_copper": { "texture": "oxidized_cut_copper" }, @@ -2027,9 +2136,24 @@ "waxed_oxidized_cut_copper_stairs": { "texture": "oxidized_cut_copper" }, + "waxed_weathered_chiseled_copper": { + "texture": "weathered_chiseled_copper" + }, "waxed_weathered_copper": { "texture": "weathered_copper" }, + "waxed_weathered_copper_bulb": { + "texture": "weathered_copper_bulb" + }, + "waxed_weathered_copper_door": { + "texture": "weathered_copper_door_top" + }, + "waxed_weathered_copper_grate": { + "texture": "weathered_copper_grate" + }, + "waxed_weathered_copper_trapdoor": { + "texture": "weathered_copper_trapdoor" + }, "waxed_weathered_cut_copper": { "texture": "weathered_cut_copper" }, @@ -2039,7 +2163,14 @@ "waxed_weathered_cut_copper_stairs": { "texture": "weathered_cut_copper" }, + "weathered_chiseled_copper": {}, "weathered_copper": {}, + "weathered_copper_bulb": {}, + "weathered_copper_door": { + "texture": "weathered_copper_door_top" + }, + "weathered_copper_grate": {}, + "weathered_copper_trapdoor": {}, "weathered_cut_copper": {}, "weathered_cut_copper_slab": { "texture": "weathered_cut_copper" diff --git a/src/core/common.rs b/src/core/common.rs index 9a94496..4241ebc 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -24,7 +24,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); /// MinedMap map tile data version number /// @@ -36,7 +36,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); /// MinedMap mipmap data version number /// From f1bc18add1e0e86f5b98612d5e6d9d689877643f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Jun 2024 11:30:20 +0200 Subject: [PATCH 068/152] minedmap-types 0.1.3 --- Cargo.lock | 2 +- crates/types/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ae562a..5c8d051 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,7 +618,7 @@ dependencies = [ [[package]] name = "minedmap-types" -version = "0.1.2" +version = "0.1.3" dependencies = [ "itertools", "serde", diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index c294466..6a81414 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-types" -version = "0.1.2" +version = "0.1.3" description = "Common types used by several MinedMap crates" edition.workspace = true license.workspace = true From 269f08d3561e267d6843a361dc4aef50ab4528b9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Jun 2024 11:30:41 +0200 Subject: [PATCH 069/152] minedmap-resource 0.4.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c8d051..4a7bb19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,7 +609,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.3.0" +version = "0.4.0" dependencies = [ "enumflags2", "glam", diff --git a/Cargo.toml b/Cargo.toml index 6fa4cdf..a8bfc58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ image = { version = "0.25.1", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.3.0", path = "crates/resource" } +minedmap-resource = { version = "0.4.0", path = "crates/resource" } minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 326e269..ea4bc95 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.3.0" +version = "0.4.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From f43e84eb2b4d1594333eca73cdb7b99bacae5851 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 23 Jun 2024 11:31:45 +0200 Subject: [PATCH 070/152] minedmap 2.2.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 318ee9a..ef41795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.2.0] - 2024-06-23 + ### Added - Added support for Minecraft 1.21 block types @@ -93,7 +95,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.1.1...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.2.0...HEAD +[2.2.0]: https://github.com/neocturne/MinedMap/compare/v2.1.1...v2.2.0 [2.1.1]: https://github.com/neocturne/MinedMap/compare/v2.1.0...v2.1.1 [2.1.0]: https://github.com/neocturne/MinedMap/compare/v2.0.2...v2.1.0 [2.0.2]: https://github.com/neocturne/MinedMap/compare/v2.0.1...v2.0.2 diff --git a/Cargo.lock b/Cargo.lock index 4a7bb19..28eb4e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,7 +566,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" -version = "2.1.1" +version = "2.2.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index a8bfc58..ddf24ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.1.1" +version = "2.2.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From f9a03b332ca9f347c74a1cabb375b1d52280cfad Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 18 Jul 2024 23:22:05 +0200 Subject: [PATCH 071/152] README.md: fix incorrect `--sign-transform` example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a07aed..2312c03 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ matches. Finally, `--sign-transform` allows to specify sed-style replacement patterns to modify the text displayed on the map. This can be used if the text matched by `--sign-prefix` or `--sign-filter` should not be displayed: -`--sign-filter 's/\[Map\]//'` would replace each occurence of "\[Map\]" with +`--sign-transform 's/\[Map\]//'` would replace each occurence of "\[Map\]" with the empty string. **Note:** On Windows, double quotes (`"`) must be used for arguments instead From 7b44ee30d6ffe631379508952e534abac36a1716 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 20 Nov 2024 14:27:30 +0100 Subject: [PATCH 072/152] Add LICENSE file again It can be useful for Github to show the license next to the repo, and it's clearer that the license applies both to the Rust code and the viewer this way. The project was relicensed from BSD-2-Clause to MIT in 2023, but the first year of the copyright is when the project started in 2015. --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2f9ad3f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2015 Matthias Schiffer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 2156bff59af32c11850ad94dd21c116925c63141 Mon Sep 17 00:00:00 2001 From: "kek.rs" <189154018+kekrs@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:05:12 +0100 Subject: [PATCH 073/152] Add Dockerfiles (#56) --- Dockerfile | 14 ++++++++++++++ Dockerfile.viewer | 3 +++ 2 files changed, 17 insertions(+) create mode 100644 Dockerfile create mode 100644 Dockerfile.viewer diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fa3627c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM docker.io/library/rust:alpine AS BUILDER + +WORKDIR /build +RUN apk update && apk add cmake build-base + +COPY src /build/src +COPY crates /build/crates +COPY Cargo.toml Cargo.lock /build +RUN cargo build -r + +FROM scratch AS RUNNER + +COPY --from=BUILDER /build/target/release/minedmap /minedmap +ENTRYPOINT [ "/minedmap" ] diff --git a/Dockerfile.viewer b/Dockerfile.viewer new file mode 100644 index 0000000..82d50bb --- /dev/null +++ b/Dockerfile.viewer @@ -0,0 +1,3 @@ +FROM docker.io/library/nginx:alpine +COPY viewer /usr/share/nginx/html +# datadir should be mounted to: /usr/share/nginx/html/data From 4933d8e15f73234717ca4eb381cbce7bab16b361 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 17 Dec 2024 00:23:57 +0100 Subject: [PATCH 074/152] treewide: clippy fixes Fix all clippy warnings as of Rust 1.83.0. --- src/core/common.rs | 2 +- src/core/entity_collector.rs | 4 ++-- src/core/tile_mipmapper.rs | 4 ++-- src/world/chunk.rs | 6 +++--- src/world/layer.rs | 2 +- src/world/section.rs | 12 ++++++------ src/world/sign.rs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 4241ebc..5f518e0 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -18,7 +18,7 @@ use crate::{ world::{block_entity::BlockEntity, layer}, }; -/// Increase to force regeneration of all output files +// Increase to force regeneration of all output files /// MinedMap processed region data version number /// diff --git a/src/core/entity_collector.rs b/src/core/entity_collector.rs index 3d9b6ab..30b3a86 100644 --- a/src/core/entity_collector.rs +++ b/src/core/entity_collector.rs @@ -16,7 +16,7 @@ pub struct EntityCollector<'a> { regions: &'a [TileCoords], } -impl<'a> TileMerger for EntityCollector<'a> { +impl TileMerger for EntityCollector<'_> { fn file_meta_version(&self) -> fs::FileMetaVersion { ENTITIES_FILE_META_VERSION } @@ -34,7 +34,7 @@ impl<'a> TileMerger for EntityCollector<'a> { } } -impl<'a> TileCollector for EntityCollector<'a> { +impl TileCollector for EntityCollector<'_> { type CollectOutput = (); fn tiles(&self) -> &[TileCoords] { diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index cd90e20..d7e54a9 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -74,7 +74,7 @@ impl<'a, P> MapMerger<'a, P> { } } -impl<'a, P: image::PixelWithColorType> TileMerger for MapMerger<'a, P> +impl TileMerger for MapMerger<'_, P> where [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, @@ -157,7 +157,7 @@ pub struct TileMipmapper<'a> { regions: &'a [TileCoords], } -impl<'a> TileCollector for TileMipmapper<'a> { +impl TileCollector for TileMipmapper<'_> { type CollectOutput = MipmapStat; fn tiles(&self) -> &[TileCoords] { diff --git a/src/world/chunk.rs b/src/world/chunk.rs index bf1d78b..daee023 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -416,13 +416,13 @@ impl<'a> Iterator for SectionIter<'a> { } } -impl<'a> DoubleEndedIterator for SectionIter<'a> { +impl DoubleEndedIterator for SectionIter<'_> { fn next_back(&mut self) -> Option { self.with_iter(|iter| iter.next_back()) } } -impl<'a> ExactSizeIterator for SectionIter<'a> { +impl ExactSizeIterator for SectionIter<'_> { fn len(&self) -> usize { match &self.inner { SectionIterInner::V1_18 { iter } => iter.len(), @@ -433,4 +433,4 @@ impl<'a> ExactSizeIterator for SectionIter<'a> { } } -impl<'a> FusedIterator for SectionIter<'a> {} +impl FusedIterator for SectionIter<'_> {} diff --git a/src/world/layer.rs b/src/world/layer.rs index 576dfa4..0764711 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -58,7 +58,7 @@ struct LayerEntry<'a> { depth: &'a mut Option, } -impl<'a> LayerEntry<'a> { +impl LayerEntry<'_> { /// Returns true if the entry has not been filled yet (no opaque block has been encountered) /// /// The depth value is filled separately when a non-water block is encountered after the block type diff --git a/src/world/section.rs b/src/world/section.rs index 62b510b..7988fd5 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -81,7 +81,7 @@ impl<'a> SectionV1_13<'a> { if let Some(block_states) = block_states { let expected_length = if aligned_blocks { let blocks_per_word = 64 / bits as usize; - (4096 + blocks_per_word - 1) / blocks_per_word + 4096usize.div_ceil(blocks_per_word) } else { 64 * bits as usize }; @@ -145,7 +145,7 @@ impl<'a> SectionV1_13<'a> { } } -impl<'a> Section for SectionV1_13<'a> { +impl Section for SectionV1_13<'_> { fn block_at(&self, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); Ok(*self @@ -188,7 +188,7 @@ impl<'a> SectionV0<'a> { } } -impl<'a> Section for SectionV0<'a> { +impl Section for SectionV0<'_> { fn block_at(&self, coords: SectionBlockCoords) -> Result> { let offset = coords.offset(); let block = self.blocks[offset] as u8; @@ -242,7 +242,7 @@ impl<'a> BiomesV1_18<'a> { if let Some(biomes) = biomes { let biomes_per_word = 64 / bits as usize; - let expected_length = (64 + biomes_per_word - 1) / biomes_per_word; + let expected_length = 64usize.div_ceil(biomes_per_word); if biomes.len() != expected_length { bail!("Invalid section biome data"); } @@ -294,7 +294,7 @@ impl<'a> BiomesV1_18<'a> { } } -impl<'a> Biomes for BiomesV1_18<'a> { +impl Biomes for BiomesV1_18<'_> { fn biome_at(&self, _section: SectionY, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); Ok(*self @@ -349,7 +349,7 @@ impl<'a> BiomesV0<'a> { } } -impl<'a> Biomes for BiomesV0<'a> { +impl Biomes for BiomesV0<'_> { fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result> { let id = match self.data { BiomesV0Data::IntArrayV15(data) => { diff --git a/src/world/sign.rs b/src/world/sign.rs index 616f7fa..57b741a 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -23,7 +23,7 @@ pub struct RawSignText<'a> { pub color: Option<&'a str>, } -impl<'a> RawSignText<'a> { +impl RawSignText<'_> { /// Decodes the [RawSignText] into a [SignText] pub fn decode(&self) -> SignText { let color = self.color.map(|c| Arc::new(c.to_owned())); From feaf90c96c5bfb01df112f6f13ac42ca5928dbd9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 17 Dec 2024 00:31:38 +0100 Subject: [PATCH 075/152] Update dependencies --- Cargo.lock | 498 +++++++++++++++---------------------- crates/resource/Cargo.toml | 2 +- 2 files changed, 208 insertions(+), 292 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28eb4e8..d32985d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,33 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -40,15 +28,15 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -61,63 +49,63 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -137,15 +125,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bytemuck" -version = "1.16.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -154,14 +142,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "cc" -version = "1.0.99" +name = "byteorder-lite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cc" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -178,9 +172,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.7" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -188,9 +182,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -201,9 +195,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -213,24 +207,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.50" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" dependencies = [ "cc", ] [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "crc32fast" @@ -243,9 +237,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -262,15 +256,15 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "enum-map" @@ -321,12 +315,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -343,18 +337,18 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "libz-ng-sys", @@ -362,16 +356,22 @@ dependencies = [ ] [[package]] -name = "futures-core" -version = "0.3.30" +name = "foldhash" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -380,15 +380,15 @@ dependencies = [ [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-macro", @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git-version" @@ -426,18 +426,19 @@ dependencies = [ [[package]] name = "glam" -version = "0.28.0" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] @@ -454,21 +455,21 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "image" -version = "0.25.1" +version = "0.25.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", "num-traits", "png", ] [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown", @@ -477,9 +478,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -492,15 +493,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -513,15 +514,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libz-ng-sys" -version = "1.1.15" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6409efc61b12687963e602df8ecf70e8ddacf95bc6576bcf16e3ac6328083c5" +checksum = "8f0f7295a34685977acb2e8cc8b08ee4a8dffd6cf278eeccddbe1ed55ba815d5" dependencies = [ "cmake", "libc", @@ -545,15 +546,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ "hashbrown", ] @@ -626,11 +627,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -674,18 +675,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.0" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "overload" @@ -713,14 +714,14 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -730,15 +731,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.13" +version = "0.17.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -749,18 +750,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -787,18 +788,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -808,9 +809,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -819,9 +820,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-demangle" @@ -831,21 +832,21 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -862,27 +863,27 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", @@ -891,11 +892,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -909,6 +911,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simd-adler32" version = "0.3.7" @@ -938,9 +946,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.67" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -949,12 +957,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -969,9 +977,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.38.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "parking_lot", @@ -980,9 +988,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -991,9 +999,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -1002,9 +1010,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -1023,9 +1031,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -1037,9 +1045,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "utf8parse" @@ -1053,12 +1061,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "winapi" version = "0.3.9" @@ -1083,186 +1085,100 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "zerocopy" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zstd" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.1.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.11+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index ea4bc95..de9b577 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -9,5 +9,5 @@ repository.workspace = true [dependencies] enumflags2 = { version = "0.7.7", features = ["serde"] } -glam = "0.28.0" +glam = "0.29.2" serde = { version = "1.0.183", features = ["derive"] } From 11e25106cfd466478b2aeec60c50d51e2b321e47 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 03:05:06 +0100 Subject: [PATCH 076/152] Update dependencies --- Cargo.lock | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d32985d..ff64b60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "autocfg" @@ -131,9 +131,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bytemuck" -version = "1.20.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" @@ -149,9 +149,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.4" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "jobserver", "libc", @@ -357,9 +357,9 @@ dependencies = [ [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "futures-core" @@ -514,9 +514,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libz-ng-sys" @@ -627,9 +627,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ "adler2", "simd-adler32", @@ -675,9 +675,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -737,9 +737,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.15" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -759,9 +759,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -863,9 +863,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -881,9 +881,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -892,9 +892,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", "memchr", @@ -946,9 +946,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", From 9b3b345318623b889f4905f1982d3ab3f6763bfa Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 03:03:06 +0100 Subject: [PATCH 077/152] resource: update block types and biomes for 1.21.4 --- CHANGELOG.md | 3 + crates/resource/src/biomes.rs | 7 + crates/resource/src/block_types.rs | 352 ++++++++++++++++++++++++++++- resource/blocks.json | 83 +++++++ src/core/common.rs | 4 +- 5 files changed, 446 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef41795..4837f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] - ReleaseDate +- Added support for Minecraft 1.21.4 block types +- Added support for Minecraft 1.21.4 Pale Garden biome + ## [2.2.0] - 2024-06-23 ### Added diff --git a/crates/resource/src/biomes.rs b/crates/resource/src/biomes.rs index 61f8339..4a0dee0 100644 --- a/crates/resource/src/biomes.rs +++ b/crates/resource/src/biomes.rs @@ -188,6 +188,13 @@ pub const BIOMES: &[(&str, Biome)] = { ("old_growth_birch_forest", Biome::new(0_60, 0_60)), ("old_growth_pine_taiga", Biome::new(0_30, 0_80)), ("old_growth_spruce_taiga", Biome::new(0_25, 0_80)), + ( + "pale_garden", + Biome::new(0_70, 0_80) + .water([118, 136, 157]) + .foliage([135, 141, 118]) + .grass([119, 130, 114]), + ), ("plains", Biome::new(0_80, 0_40)), ("river", Biome::new(0_50, 0_50)), ("savanna", Biome::new(2_00, 0_00)), diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index cbfe1b7..4cdc55c 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -1868,7 +1868,7 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ ConstBlockType { block_color: BlockColor { flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([47, 23, 28]), + color: Color([45, 22, 27]), }, sign_material: None, }, @@ -1903,6 +1903,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "chiseled_resin_bricks", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([200, 84, 24]), + }, + sign_material: None, + }, + ), ( "chiseled_sandstone", ConstBlockType { @@ -1973,6 +1983,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "closed_eyeblossom", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "coal_block", ConstBlockType { @@ -2283,6 +2303,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "creaking_heart", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([73, 59, 54]), + }, + sign_material: None, + }, + ), ( "creeper_head", ConstBlockType { @@ -6253,6 +6283,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "open_eyeblossom", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "orange_banner", ConstBlockType { @@ -6523,6 +6563,206 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "pale_hanging_moss", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), + ( + "pale_moss_block", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 112, 104]), + }, + sign_material: None, + }, + ), + ( + "pale_moss_carpet", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([106, 112, 104]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_button", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_door", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([216, 208, 206]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_fence", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_fence_gate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_hanging_sign", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("pale_oak"), + }, + ), + ( + "pale_oak_leaves", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([116, 121, 114]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_log", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 189, 187]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_planks", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_pressure_plate", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_sapling", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 105, 99]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_sign", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: Some("pale_oak"), + }, + ), + ( + "pale_oak_slab", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_stairs", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([227, 217, 216]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_trapdoor", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 220, 218]), + }, + sign_material: None, + }, + ), + ( + "pale_oak_wall_hanging_sign", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("pale_oak"), + }, + ), + ( + "pale_oak_wall_sign", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{WallSign}), + color: Color([0, 0, 0]), + }, + sign_material: Some("pale_oak"), + }, + ), + ( + "pale_oak_wood", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([87, 77, 75]), + }, + sign_material: None, + }, + ), ( "pearlescent_froglight", ConstBlockType { @@ -7213,6 +7453,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "potted_closed_eyeblossom", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([108, 98, 101]), + }, + sign_material: None, + }, + ), ( "potted_cornflower", ConstBlockType { @@ -7333,6 +7583,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "potted_open_eyeblossom", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([133, 124, 127]), + }, + sign_material: None, + }, + ), ( "potted_orange_tulip", ConstBlockType { @@ -7353,6 +7613,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "potted_pale_oak_sapling", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([109, 105, 99]), + }, + sign_material: None, + }, + ), ( "potted_pink_tulip", ConstBlockType { @@ -8193,6 +8463,66 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "resin_block", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([217, 99, 25]), + }, + sign_material: None, + }, + ), + ( + "resin_brick_slab", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([205, 88, 24]), + }, + sign_material: None, + }, + ), + ( + "resin_brick_stairs", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([205, 88, 24]), + }, + sign_material: None, + }, + ), + ( + "resin_brick_wall", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([205, 88, 24]), + }, + sign_material: None, + }, + ), + ( + "resin_bricks", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([205, 88, 24]), + }, + sign_material: None, + }, + ), + ( + "resin_clump", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "respawn_anchor", ConstBlockType { @@ -9173,6 +9503,26 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "stripped_pale_oak_log", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([235, 226, 225]), + }, + sign_material: None, + }, + ), + ( + "stripped_pale_oak_wood", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([245, 238, 236]), + }, + sign_material: None, + }, + ), ( "stripped_spruce_log", ConstBlockType { diff --git a/resource/blocks.json b/resource/blocks.json index 9d70f96..a88aa34 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -416,6 +416,7 @@ "chiseled_red_sandstone": { "texture": "red_sandstone_top" }, + "chiseled_resin_bricks": {}, "chiseled_sandstone": { "texture": "sandstone_top" }, @@ -427,6 +428,7 @@ "chorus_flower": {}, "chorus_plant": {}, "clay": {}, + "closed_eyeblossom": null, "coal_block": {}, "coal_ore": {}, "coarse_dirt": {}, @@ -482,6 +484,9 @@ "crafting_table": { "texture": "crafting_table_top" }, + "creaking_heart": { + "texture": "creaking_heart_top" + }, "creeper_head": null, "creeper_wall_head": null, "crimson_button": null, @@ -1269,6 +1274,7 @@ "ochre_froglight": { "texture": "ochre_froglight_top" }, + "open_eyeblossom": null, "orange_banner": null, "orange_bed": null, "orange_candle": null, @@ -1308,6 +1314,56 @@ }, "packed_ice": {}, "packed_mud": {}, + "pale_hanging_moss": null, + "pale_moss_block": {}, + "pale_moss_carpet": {}, + "pale_oak_button": null, + "pale_oak_door": { + "texture": "pale_oak_door_top" + }, + "pale_oak_fence": { + "texture": "pale_oak_planks" + }, + "pale_oak_fence_gate": { + "texture": "pale_oak_planks" + }, + "pale_oak_hanging_sign": { + "sign_material": "pale_oak", + "texture": null + }, + "pale_oak_leaves": {}, + "pale_oak_log": { + "texture": "pale_oak_log_top" + }, + "pale_oak_planks": {}, + "pale_oak_pressure_plate": { + "texture": "pale_oak_planks" + }, + "pale_oak_sapling": {}, + "pale_oak_sign": { + "sign_material": "pale_oak", + "texture": null + }, + "pale_oak_slab": { + "texture": "pale_oak_planks" + }, + "pale_oak_stairs": { + "texture": "pale_oak_planks" + }, + "pale_oak_trapdoor": {}, + "pale_oak_wall_hanging_sign": { + "sign_material": "pale_oak", + "texture": null, + "wall_sign": true + }, + "pale_oak_wall_sign": { + "sign_material": "pale_oak", + "texture": null, + "wall_sign": true + }, + "pale_oak_wood": { + "texture": "pale_oak_log" + }, "pearlescent_froglight": { "texture": "pearlescent_froglight_top" }, @@ -1463,6 +1519,9 @@ "potted_cherry_sapling": { "texture": "cherry_sapling" }, + "potted_closed_eyeblossom": { + "texture": "closed_eyeblossom" + }, "potted_cornflower": { "texture": "cornflower" }, @@ -1500,12 +1559,18 @@ "potted_oak_sapling": { "texture": "oak_sapling" }, + "potted_open_eyeblossom": { + "texture": "open_eyeblossom" + }, "potted_orange_tulip": { "texture": "orange_tulip" }, "potted_oxeye_daisy": { "texture": "oxeye_daisy" }, + "potted_pale_oak_sapling": { + "texture": "pale_oak_sapling" + }, "potted_pink_tulip": { "texture": "pink_tulip" }, @@ -1668,6 +1733,18 @@ "repeating_command_block": { "texture": "repeating_command_block_front" }, + "resin_block": {}, + "resin_brick_slab": { + "texture": "resin_bricks" + }, + "resin_brick_stairs": { + "texture": "resin_bricks" + }, + "resin_brick_wall": { + "texture": "resin_bricks" + }, + "resin_bricks": {}, + "resin_clump": null, "respawn_anchor": { "texture": "respawn_anchor_top" }, @@ -1903,6 +1980,12 @@ "stripped_oak_wood": { "texture": "stripped_oak_log" }, + "stripped_pale_oak_log": { + "texture": "stripped_pale_oak_log_top" + }, + "stripped_pale_oak_wood": { + "texture": "stripped_pale_oak_log" + }, "stripped_spruce_log": { "texture": "stripped_spruce_log_top" }, diff --git a/src/core/common.rs b/src/core/common.rs index 5f518e0..3dd01cf 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -24,7 +24,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3); /// MinedMap map tile data version number /// @@ -36,7 +36,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3); /// MinedMap mipmap data version number /// From 83bd936f8073477aa5bae6e059ac84f3430b7623 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 03:54:45 +0100 Subject: [PATCH 078/152] viewer: add images for pale oak signs --- CHANGELOG.md | 1 + resource/sign_textures.py | 1 + viewer/images/bg/pale_oak_hanging_sign.png | Bin 0 -> 318 bytes viewer/images/bg/pale_oak_hanging_wall_sign.png | Bin 0 -> 222 bytes viewer/images/bg/pale_oak_sign.png | Bin 0 -> 419 bytes viewer/images/bg/pale_oak_wall_sign.png | Bin 0 -> 317 bytes viewer/images/icon/pale_oak_hanging_sign.png | Bin 0 -> 258 bytes viewer/images/icon/pale_oak_hanging_wall_sign.png | Bin 0 -> 320 bytes viewer/images/icon/pale_oak_sign.png | Bin 0 -> 281 bytes viewer/images/icon/pale_oak_wall_sign.png | Bin 0 -> 223 bytes 10 files changed, 2 insertions(+) create mode 100644 viewer/images/bg/pale_oak_hanging_sign.png create mode 100644 viewer/images/bg/pale_oak_hanging_wall_sign.png create mode 100644 viewer/images/bg/pale_oak_sign.png create mode 100644 viewer/images/bg/pale_oak_wall_sign.png create mode 100644 viewer/images/icon/pale_oak_hanging_sign.png create mode 100644 viewer/images/icon/pale_oak_hanging_wall_sign.png create mode 100644 viewer/images/icon/pale_oak_sign.png create mode 100644 viewer/images/icon/pale_oak_wall_sign.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 4837f71..8c7c159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added support for Minecraft 1.21.4 block types - Added support for Minecraft 1.21.4 Pale Garden biome +- viewer: added images for pale oak signs ## [2.2.0] - 2024-06-23 diff --git a/resource/sign_textures.py b/resource/sign_textures.py index e0b548d..846ab3e 100755 --- a/resource/sign_textures.py +++ b/resource/sign_textures.py @@ -15,6 +15,7 @@ MATERIALS = [ 'jungle', 'mangrove', 'oak', + 'pale_oak', 'spruce', 'warped', ] diff --git a/viewer/images/bg/pale_oak_hanging_sign.png b/viewer/images/bg/pale_oak_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..972a1198913ddf65b573328cfc63307d83262971 GIT binary patch literal 318 zcmV-E0m1%>P)%F3FNDE~wzKhYBA23wrV&`1=Jf#Zp$WuwfH&STD|)#6tT{GcPl5-b~;Z z_m5BW^ULeZ8Ps)43AWpZbG;|)mU;5AKU^e|*QtOXzblOfW3iEOJ#I_FOEYSzT zUpVYdh1cC%Tm0CsQh7;8!K8{_T>lh?*Dc~VTQ`(AT^<1myfG^Q!k z#f`u?OPD;ib;SxQU|Yw!?={YO5l=A{!&D%QqgrcBqmyO#Q+KdkS2{>B{j(^d!iht1 zq5`5O5Bah3srikCY!-wZjUq5*8 z~;d-IRiu=z4;&+546`%Y^0hY3j=S`-zs?ORwl<24`cXFQcBBdbx( RSqQY5!PC{xWt~$(696plRpI~u literal 0 HcmV?d00001 diff --git a/viewer/images/bg/pale_oak_sign.png b/viewer/images/bg/pale_oak_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..5ea5a7e6992dee3775bc146224c071b067bf3150 GIT binary patch literal 419 zcmV;U0bKrxP)%$w zoHH6(5;u^LrzwIc!l7ER-va<@&U?M#tdS*gL&KhJcjTILn2e$39Hpq>I;Suh>&*?t zRD3H>(_eJ}CS&ky8%2AV$rvEsdt1rd_in1-8;_e!&mw~BF_Z;YwPwvw&&ZOvneupO zhYC}CD^F9DqC(IX>A<0%1j>cJ04DiX5JfHDtpTkuC&drAS zhWsC>yj0ca&H;c$R|5Jr(DS95Os1O59pf7>+oy(_?m0;OgRh zS%G8lzXbds#L97&6VQF4+5&zM!gbD;6953;_m>sWg{3pRdwbOu_y!nc>6`7lvb6vJ N002ovPDHLkV1isf#y$W5 literal 0 HcmV?d00001 diff --git a/viewer/images/bg/pale_oak_wall_sign.png b/viewer/images/bg/pale_oak_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..f52f32a7d94663cf290959191ca6fdc025ff461d GIT binary patch literal 317 zcmV-D0mA-?P)>83qJ{;A-gmpP_HitC<`0Lbnr?2!hy%vlz=xB>ucjpsHR~<-J5Tbv5Im zwU(kRIg53#7XXuUL2g^Cn!1{$IM;e5PtK7T!{i+OFp_09!I*=Gc zt~K4#EHMU#-(V|$`{1S#zIxp6fkc8VH}sv0r7qP-PBnEkA8EXmBZeb>+FDCLj1)^y z8gBIzh%a&ihy1iCOIUo!wcgcN4EBcrobjU`Wch!yn7&uN5x(;OK}^e7{AwLQDp!I~ z26?^`^T`tPxqE!|{P~_GDY~t1c`>*jMsBySwdvNMBmV9`5Qv@-_v8$JT5!{^Nq>~0 P00000NkvXXu0mjf7T1hl literal 0 HcmV?d00001 diff --git a/viewer/images/icon/pale_oak_hanging_sign.png b/viewer/images/icon/pale_oak_hanging_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..cd61dd1dcfbfa1a2e9c06ba831b0a0e61d4f3c5e GIT binary patch literal 258 zcmV+d0sa1oP)s~sIMSIs6%PQAx??cYC*r{F8AN%{saU? zQ8*?TYq3wVEORnSzG<;+sH!TO+BnuC0Qa;G;L%wCW{dg9px12Qv0SaA#1{``$#%aB zqNk}fS7U;9KAzrIZQqe9MN{k0>>B`5rNa55_0a0w+@_v4ps6*RJda}O-`{#Zo(8#$ zS7QK3yw#@Gq)G*AzIj|5Sha2I< zXFYS$=AibxZ9f1QhJkeZ&aJoyV97qy6nz{CzKV)YDcZIr3`6?9rz%QZ zxonqZL_*9sNs<^=v}C?b;y5;LboCeW-G)5Ry|o*c%mXkdZ2*2o4ZzjS_1Q+t^l{|w z;n53hahGL0zrIY+s;MQNQWLX-^KD}!1WhfcW_PlY5Yzfw%DL5p+OIutrlyuWZ8o0o z`nRW6MLEme*eL}-V68T_oIcjZswmHDGpl+Sj60A^tOfwPEW2ovtH8bfKl%k9Xq~a< Sohjh}00006oETfx2tOIl`hn&9^k*{X?B+M*9Z8mDk9q&bfJ8F zH@iyz{io|ii`o2cpi@*T^)M9lnO~n%2T(T+E4{wB3HzYQ_~T|$F9h)Z_WC$ f+5S*B%~j|KBPVsS?i`Z{00000NkvXXu0mjfpwD|G literal 0 HcmV?d00001 diff --git a/viewer/images/icon/pale_oak_wall_sign.png b/viewer/images/icon/pale_oak_wall_sign.png new file mode 100644 index 0000000000000000000000000000000000000000..32257e320475d351df1607727cd8a1774fa5b26a GIT binary patch literal 223 zcmV<503iQ~P)3XJW0001{Nkls!9uU6|U4Lr&^Z}mMlKItPl#cbsJtlqof6vRBs=f>y$|kLU ZhF(rdXtH}uT$%s?002ovPDHLkV1i-1UO@l= literal 0 HcmV?d00001 From 00216341ca27d297697014a255642e88d703dd6c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 12:58:47 +0100 Subject: [PATCH 079/152] resource: separate current biome data from aliases/legacy IDs Prepare for automatic generation of current biome data. --- crates/resource/src/biomes.rs | 311 +-------------------------- crates/resource/src/legacy_biomes.rs | 202 +++++++++++++++++ crates/resource/src/lib.rs | 110 +++++++++- 3 files changed, 311 insertions(+), 312 deletions(-) create mode 100644 crates/resource/src/legacy_biomes.rs diff --git a/crates/resource/src/biomes.rs b/crates/resource/src/biomes.rs index 4a0dee0..d81a069 100644 --- a/crates/resource/src/biomes.rs +++ b/crates/resource/src/biomes.rs @@ -1,112 +1,6 @@ -//! Biome data structures +//! Biome data -use serde::{Deserialize, Serialize}; - -use super::Color; - -/// Grass color modifier used by a biome -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum BiomeGrassColorModifier { - /// Grass color modifier used by the dark forest biome - DarkForest, - /// Grass color modifier used by swamp biomes - Swamp, -} - -/// A biome specification -/// -/// A Biome contains all information about a biome necessary to compute a block -/// color given a block type and depth -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct Biome { - /// Temperature value - /// - /// For more efficient storage, the temperature is stored as an integer - /// after mutiplying the raw value by 20 - pub temp: i8, - /// Downfall value - /// - /// For more efficient storage, the downfall is stored as an integer - /// after mutiplying the raw value by 20 - pub downfall: i8, - /// Water color override - pub water_color: Option, - /// Foliage color override - pub foliage_color: Option, - /// Grass color override - pub grass_color: Option, - /// Grass color modifier - pub grass_color_modifier: Option, -} - -impl Biome { - /// Constructs a new Biome - const fn new(temp: i16, downfall: i16) -> Biome { - /// Helper to encode temperature and downfall values - /// - /// Converts temperatue and downfall from the input format - /// (mutiplied by 100) to i8 range for more efficient storage. - const fn encode(v: i16) -> i8 { - (v / 5) as i8 - } - Biome { - temp: encode(temp), - downfall: encode(downfall), - grass_color_modifier: None, - water_color: None, - foliage_color: None, - grass_color: None, - } - } - - /// Builder function to override the biome water color - const fn water(self, water_color: [u8; 3]) -> Biome { - Biome { - water_color: Some(Color(water_color)), - ..self - } - } - - /// Builder function to override the biome foliage color - const fn foliage(self, foliage_color: [u8; 3]) -> Biome { - Biome { - foliage_color: Some(Color(foliage_color)), - ..self - } - } - - /// Builder function to override the biome grass color - const fn grass(self, grass_color: [u8; 3]) -> Biome { - Biome { - grass_color: Some(Color(grass_color)), - ..self - } - } - - /// Builder function to set a grass color modifier - const fn modify(self, grass_color_modifier: BiomeGrassColorModifier) -> Biome { - Biome { - grass_color_modifier: Some(grass_color_modifier), - ..self - } - } - - /// Decodes a temperature or downfall value from the storage format to - /// f32 for further calculation - fn decode(val: i8) -> f32 { - f32::from(val) / 20.0 - } - - /// Returns the biome's temperature decoded to its original float value - pub fn temp(&self) -> f32 { - Self::decode(self.temp) - } - - /// Returns the biome's downfall decoded to its original float value - pub fn downfall(&self) -> f32 { - Self::decode(self.downfall) - } -} +use super::*; /// Standard biome specifications pub const BIOMES: &[(&str, Biome)] = { @@ -241,204 +135,3 @@ pub const BIOMES: &[(&str, Biome)] = { ("the_end", Biome::new(0_50, 0_50)), ] }; - -/// Biome ID aliases -/// -/// Some biomes have been renamed or merged in recent Minecraft versions. -/// Maintain a list of aliases to support chunks saved by older versions. -pub const BIOME_ALIASES: &[(&str, &str)] = &[ - // Biomes fix - ("beaches", "beach"), - ("cold_beach", "snowy_beach"), - ("cold_deep_ocean", "deep_cold_ocean"), - ("extreme_hills", "mountains"), - ("extreme_hills_with_trees", "wooded_mountains"), - ("forest_hills", "wooded_hills"), - ("frozen_deep_ocean", "deep_frozen_ocean"), - ("hell", "nether_wastes"), - ("ice_flats", "snowy_tundra"), - ("ice_mountains", "snowy_mountains"), - ("lukewarm_deep_ocean", "deep_lukewarm_ocean"), - ("mesa", "badlands"), - ("mesa_clear_rock", "badlands_plateau"), - ("mesa_rock", "wooded_badlands_plateau"), - ("mushroom_island", "mushroom_fields"), - ("mushroom_island_shore", "mushroom_field_shore"), - ("mutated_birch_forest", "tall_birch_forest"), - ("mutated_birch_forest_hills", "tall_birch_hills"), - ("mutated_desert", "desert_lakes"), - ("mutated_extreme_hills", "gravelly_mountains"), - ( - "mutated_extreme_hills_with_trees", - "modified_gravelly_mountains", - ), - ("mutated_forest", "flower_forest"), - ("mutated_ice_flats", "ice_spikes"), - ("mutated_jungle", "modified_jungle"), - ("mutated_jungle_edge", "modified_jungle_edge"), - ("mutated_mesa", "eroded_badlands"), - ("mutated_mesa_clear_rock", "modified_badlands_plateau"), - ("mutated_mesa_rock", "modified_wooded_badlands_plateau"), - ("mutated_plains", "sunflower_plains"), - ("mutated_redwood_taiga", "giant_spruce_taiga"), - ("mutated_redwood_taiga_hills", "giant_spruce_taiga_hills"), - ("mutated_roofed_forest", "dark_forest_hills"), - ("mutated_savanna", "shattered_savanna"), - ("mutated_savanna_rock", "shattered_savanna_plateau"), - ("mutated_swampland", "swamp_hills"), - ("mutated_taiga", "taiga_mountains"), - ("mutated_taiga_cold", "snowy_taiga_mountains"), - ("redwood_taiga", "giant_tree_taiga"), - ("redwood_taiga_hills", "giant_tree_taiga_hills"), - ("roofed_forest", "dark_forest"), - ("savanna_rock", "savanna_plateau"), - ("sky", "the_end"), - ("sky_island_barren", "end_barrens"), - ("sky_island_high", "end_highlands"), - ("sky_island_low", "small_end_islands"), - ("sky_island_medium", "end_midlands"), - ("smaller_extreme_hills", "mountain_edge"), - ("stone_beach", "stone_shore"), - ("swampland", "swamp"), - ("taiga_cold", "snowy_taiga"), - ("taiga_cold_hills", "snowy_taiga_hills"), - ("void", "the_void"), - ("warm_deep_ocean", "deep_warm_ocean"), - // Nether biome rename - ("nether", "nether_wastes"), - // Caves and Cliffs biome renames - ("badlands_plateau", "badlands"), - ("bamboo_jungle_hills", "bamboo_jungle"), - ("birch_forest_hills", "birch_forest"), - ("dark_forest_hills", "dark_forest"), - ("desert_hills", "desert"), - ("desert_lakes", "desert"), - ("giant_spruce_taiga", "old_growth_spruce_taiga"), - ("giant_spruce_taiga_hills", "old_growth_spruce_taiga"), - ("giant_tree_taiga", "old_growth_pine_taiga"), - ("giant_tree_taiga_hills", "old_growth_pine_taiga"), - ("gravelly_mountains", "windswept_gravelly_hills"), - ("jungle_edge", "sparse_jungle"), - ("jungle_hills", "jungle"), - ("lofty_peaks", "jagged_peaks"), - ("modified_badlands_plateau", "badlands"), - ("modified_gravelly_mountains", "windswept_gravelly_hills"), - ("modified_jungle", "jungle"), - ("modified_jungle_edge", "sparse_jungle"), - ("modified_wooded_badlands_plateau", "wooded_badlands"), - ("mountain_edge", "windswept_hills"), - ("mountains", "windswept_hills"), - ("mushroom_field_shore", "mushroom_fields"), - ("shattered_savanna", "windswept_savanna"), - ("shattered_savanna_plateau", "windswept_savanna"), - ("snowcapped_peaks", "frozen_peaks"), - ("snowy_mountains", "snowy_plains"), - ("snowy_taiga_hills", "snowy_taiga"), - ("snowy_taiga_mountains", "snowy_taiga"), - ("snowy_tundra", "snowy_plains"), - ("stone_shore", "stony_shore"), - ("swamp_hills", "swamp"), - ("taiga_hills", "taiga"), - ("taiga_mountains", "taiga"), - ("tall_birch_forest", "old_growth_birch_forest"), - ("tall_birch_hills", "old_growth_birch_forest"), - ("wooded_badlands_plateau", "wooded_badlands"), - ("wooded_hills", "forest"), - ("wooded_mountains", "windswept_forest"), - // Remove Deep Warm Ocean - ("deep_warm_ocean", "warm_ocean"), -]; - -/// Maps old numeric biome IDs to new string IDs -pub fn legacy_biome(index: u8) -> &'static str { - match index { - 0 => "ocean", - 1 => "plains", - 2 => "desert", - 3 => "mountains", - 4 => "forest", - 5 => "taiga", - 6 => "swamp", - 7 => "river", - 8 => "nether_wastes", - 9 => "the_end", - 10 => "frozen_ocean", - 11 => "frozen_river", - 12 => "snowy_tundra", - 13 => "snowy_mountains", - 14 => "mushroom_fields", - 15 => "mushroom_field_shore", - 16 => "beach", - 17 => "desert_hills", - 18 => "wooded_hills", - 19 => "taiga_hills", - 20 => "mountain_edge", - 21 => "jungle", - 22 => "jungle_hills", - 23 => "jungle_edge", - 24 => "deep_ocean", - 25 => "stone_shore", - 26 => "snowy_beach", - 27 => "birch_forest", - 28 => "birch_forest_hills", - 29 => "dark_forest", - 30 => "snowy_taiga", - 31 => "snowy_taiga_hills", - 32 => "giant_tree_taiga", - 33 => "giant_tree_taiga_hills", - 34 => "wooded_mountains", - 35 => "savanna", - 36 => "savanna_plateau", - 37 => "badlands", - 38 => "wooded_badlands_plateau", - 39 => "badlands_plateau", - 40 => "small_end_islands", - 41 => "end_midlands", - 42 => "end_highlands", - 43 => "end_barrens", - 44 => "warm_ocean", - 45 => "lukewarm_ocean", - 46 => "cold_ocean", - 47 => "deep_warm_ocean", - 48 => "deep_lukewarm_ocean", - 49 => "deep_cold_ocean", - 50 => "deep_frozen_ocean", - 127 => "the_void", - 129 => "sunflower_plains", - 130 => "desert_lakes", - 131 => "gravelly_mountains", - 132 => "flower_forest", - 133 => "taiga_mountains", - 134 => "swamp_hills", - 140 => "ice_spikes", - 149 => "modified_jungle", - 151 => "modified_jungle_edge", - 155 => "tall_birch_forest", - 156 => "tall_birch_hills", - 157 => "dark_forest_hills", - 158 => "snowy_taiga_mountains", - 160 => "giant_spruce_taiga", - 161 => "giant_spruce_taiga_hills", - 162 => "modified_gravelly_mountains", - 163 => "shattered_savanna", - 164 => "shattered_savanna_plateau", - 165 => "eroded_badlands", - 166 => "modified_wooded_badlands_plateau", - 167 => "modified_badlands_plateau", - 168 => "bamboo_jungle", - 169 => "bamboo_jungle_hills", - 170 => "soul_sand_valley", - 171 => "crimson_forest", - 172 => "warped_forest", - 173 => "basalt_deltas", - 174 => "dripstone_caves", - 175 => "lush_caves", - 177 => "meadow", - 178 => "grove", - 179 => "snowy_slopes", - 180 => "snowcapped_peaks", - 181 => "lofty_peaks", - 182 => "stony_peaks", - _ => "ocean", - } -} diff --git a/crates/resource/src/legacy_biomes.rs b/crates/resource/src/legacy_biomes.rs new file mode 100644 index 0000000..d980823 --- /dev/null +++ b/crates/resource/src/legacy_biomes.rs @@ -0,0 +1,202 @@ +//! Manually maintained biome data (aliases and legacy biome IDs) + +/// Biome ID aliases +/// +/// Some biomes have been renamed or merged in recent Minecraft versions. +/// Maintain a list of aliases to support chunks saved by older versions. +pub const BIOME_ALIASES: &[(&str, &str)] = &[ + // Biomes fix + ("beaches", "beach"), + ("cold_beach", "snowy_beach"), + ("cold_deep_ocean", "deep_cold_ocean"), + ("extreme_hills", "mountains"), + ("extreme_hills_with_trees", "wooded_mountains"), + ("forest_hills", "wooded_hills"), + ("frozen_deep_ocean", "deep_frozen_ocean"), + ("hell", "nether_wastes"), + ("ice_flats", "snowy_tundra"), + ("ice_mountains", "snowy_mountains"), + ("lukewarm_deep_ocean", "deep_lukewarm_ocean"), + ("mesa", "badlands"), + ("mesa_clear_rock", "badlands_plateau"), + ("mesa_rock", "wooded_badlands_plateau"), + ("mushroom_island", "mushroom_fields"), + ("mushroom_island_shore", "mushroom_field_shore"), + ("mutated_birch_forest", "tall_birch_forest"), + ("mutated_birch_forest_hills", "tall_birch_hills"), + ("mutated_desert", "desert_lakes"), + ("mutated_extreme_hills", "gravelly_mountains"), + ( + "mutated_extreme_hills_with_trees", + "modified_gravelly_mountains", + ), + ("mutated_forest", "flower_forest"), + ("mutated_ice_flats", "ice_spikes"), + ("mutated_jungle", "modified_jungle"), + ("mutated_jungle_edge", "modified_jungle_edge"), + ("mutated_mesa", "eroded_badlands"), + ("mutated_mesa_clear_rock", "modified_badlands_plateau"), + ("mutated_mesa_rock", "modified_wooded_badlands_plateau"), + ("mutated_plains", "sunflower_plains"), + ("mutated_redwood_taiga", "giant_spruce_taiga"), + ("mutated_redwood_taiga_hills", "giant_spruce_taiga_hills"), + ("mutated_roofed_forest", "dark_forest_hills"), + ("mutated_savanna", "shattered_savanna"), + ("mutated_savanna_rock", "shattered_savanna_plateau"), + ("mutated_swampland", "swamp_hills"), + ("mutated_taiga", "taiga_mountains"), + ("mutated_taiga_cold", "snowy_taiga_mountains"), + ("redwood_taiga", "giant_tree_taiga"), + ("redwood_taiga_hills", "giant_tree_taiga_hills"), + ("roofed_forest", "dark_forest"), + ("savanna_rock", "savanna_plateau"), + ("sky", "the_end"), + ("sky_island_barren", "end_barrens"), + ("sky_island_high", "end_highlands"), + ("sky_island_low", "small_end_islands"), + ("sky_island_medium", "end_midlands"), + ("smaller_extreme_hills", "mountain_edge"), + ("stone_beach", "stone_shore"), + ("swampland", "swamp"), + ("taiga_cold", "snowy_taiga"), + ("taiga_cold_hills", "snowy_taiga_hills"), + ("void", "the_void"), + ("warm_deep_ocean", "deep_warm_ocean"), + // Nether biome rename + ("nether", "nether_wastes"), + // Caves and Cliffs biome renames + ("badlands_plateau", "badlands"), + ("bamboo_jungle_hills", "bamboo_jungle"), + ("birch_forest_hills", "birch_forest"), + ("dark_forest_hills", "dark_forest"), + ("desert_hills", "desert"), + ("desert_lakes", "desert"), + ("giant_spruce_taiga", "old_growth_spruce_taiga"), + ("giant_spruce_taiga_hills", "old_growth_spruce_taiga"), + ("giant_tree_taiga", "old_growth_pine_taiga"), + ("giant_tree_taiga_hills", "old_growth_pine_taiga"), + ("gravelly_mountains", "windswept_gravelly_hills"), + ("jungle_edge", "sparse_jungle"), + ("jungle_hills", "jungle"), + ("lofty_peaks", "jagged_peaks"), + ("modified_badlands_plateau", "badlands"), + ("modified_gravelly_mountains", "windswept_gravelly_hills"), + ("modified_jungle", "jungle"), + ("modified_jungle_edge", "sparse_jungle"), + ("modified_wooded_badlands_plateau", "wooded_badlands"), + ("mountain_edge", "windswept_hills"), + ("mountains", "windswept_hills"), + ("mushroom_field_shore", "mushroom_fields"), + ("shattered_savanna", "windswept_savanna"), + ("shattered_savanna_plateau", "windswept_savanna"), + ("snowcapped_peaks", "frozen_peaks"), + ("snowy_mountains", "snowy_plains"), + ("snowy_taiga_hills", "snowy_taiga"), + ("snowy_taiga_mountains", "snowy_taiga"), + ("snowy_tundra", "snowy_plains"), + ("stone_shore", "stony_shore"), + ("swamp_hills", "swamp"), + ("taiga_hills", "taiga"), + ("taiga_mountains", "taiga"), + ("tall_birch_forest", "old_growth_birch_forest"), + ("tall_birch_hills", "old_growth_birch_forest"), + ("wooded_badlands_plateau", "wooded_badlands"), + ("wooded_hills", "forest"), + ("wooded_mountains", "windswept_forest"), + // Remove Deep Warm Ocean + ("deep_warm_ocean", "warm_ocean"), +]; + +/// Maps old numeric biome IDs to new string IDs +pub fn legacy_biome(index: u8) -> &'static str { + match index { + 0 => "ocean", + 1 => "plains", + 2 => "desert", + 3 => "mountains", + 4 => "forest", + 5 => "taiga", + 6 => "swamp", + 7 => "river", + 8 => "nether_wastes", + 9 => "the_end", + 10 => "frozen_ocean", + 11 => "frozen_river", + 12 => "snowy_tundra", + 13 => "snowy_mountains", + 14 => "mushroom_fields", + 15 => "mushroom_field_shore", + 16 => "beach", + 17 => "desert_hills", + 18 => "wooded_hills", + 19 => "taiga_hills", + 20 => "mountain_edge", + 21 => "jungle", + 22 => "jungle_hills", + 23 => "jungle_edge", + 24 => "deep_ocean", + 25 => "stone_shore", + 26 => "snowy_beach", + 27 => "birch_forest", + 28 => "birch_forest_hills", + 29 => "dark_forest", + 30 => "snowy_taiga", + 31 => "snowy_taiga_hills", + 32 => "giant_tree_taiga", + 33 => "giant_tree_taiga_hills", + 34 => "wooded_mountains", + 35 => "savanna", + 36 => "savanna_plateau", + 37 => "badlands", + 38 => "wooded_badlands_plateau", + 39 => "badlands_plateau", + 40 => "small_end_islands", + 41 => "end_midlands", + 42 => "end_highlands", + 43 => "end_barrens", + 44 => "warm_ocean", + 45 => "lukewarm_ocean", + 46 => "cold_ocean", + 47 => "deep_warm_ocean", + 48 => "deep_lukewarm_ocean", + 49 => "deep_cold_ocean", + 50 => "deep_frozen_ocean", + 127 => "the_void", + 129 => "sunflower_plains", + 130 => "desert_lakes", + 131 => "gravelly_mountains", + 132 => "flower_forest", + 133 => "taiga_mountains", + 134 => "swamp_hills", + 140 => "ice_spikes", + 149 => "modified_jungle", + 151 => "modified_jungle_edge", + 155 => "tall_birch_forest", + 156 => "tall_birch_hills", + 157 => "dark_forest_hills", + 158 => "snowy_taiga_mountains", + 160 => "giant_spruce_taiga", + 161 => "giant_spruce_taiga_hills", + 162 => "modified_gravelly_mountains", + 163 => "shattered_savanna", + 164 => "shattered_savanna_plateau", + 165 => "eroded_badlands", + 166 => "modified_wooded_badlands_plateau", + 167 => "modified_badlands_plateau", + 168 => "bamboo_jungle", + 169 => "bamboo_jungle_hills", + 170 => "soul_sand_valley", + 171 => "crimson_forest", + 172 => "warped_forest", + 173 => "basalt_deltas", + 174 => "dripstone_caves", + 175 => "lush_caves", + 177 => "meadow", + 178 => "grove", + 179 => "snowy_slopes", + 180 => "snowcapped_peaks", + 181 => "lofty_peaks", + 182 => "stony_peaks", + _ => "ocean", + } +} diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index 1baffda..b499fbf 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -4,6 +4,7 @@ mod biomes; mod block_color; +mod legacy_biomes; mod legacy_block_types; #[allow(clippy::missing_docs_in_private_items)] // Generated module @@ -135,9 +136,112 @@ impl BlockTypes { } } -pub use biomes::{Biome, BiomeGrassColorModifier}; pub use block_color::{block_color, needs_biome}; +/// Grass color modifier used by a biome +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum BiomeGrassColorModifier { + /// Grass color modifier used by the dark forest biome + DarkForest, + /// Grass color modifier used by swamp biomes + Swamp, +} + +/// A biome specification +/// +/// A Biome contains all information about a biome necessary to compute a block +/// color given a block type and depth +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct Biome { + /// Temperature value + /// + /// For more efficient storage, the temperature is stored as an integer + /// after mutiplying the raw value by 20 + pub temp: i8, + /// Downfall value + /// + /// For more efficient storage, the downfall is stored as an integer + /// after mutiplying the raw value by 20 + pub downfall: i8, + /// Water color override + pub water_color: Option, + /// Foliage color override + pub foliage_color: Option, + /// Grass color override + pub grass_color: Option, + /// Grass color modifier + pub grass_color_modifier: Option, +} + +impl Biome { + /// Constructs a new Biome + const fn new(temp: i16, downfall: i16) -> Biome { + /// Helper to encode temperature and downfall values + /// + /// Converts temperatue and downfall from the input format + /// (mutiplied by 100) to i8 range for more efficient storage. + const fn encode(v: i16) -> i8 { + (v / 5) as i8 + } + Biome { + temp: encode(temp), + downfall: encode(downfall), + grass_color_modifier: None, + water_color: None, + foliage_color: None, + grass_color: None, + } + } + + /// Builder function to override the biome water color + const fn water(self, water_color: [u8; 3]) -> Biome { + Biome { + water_color: Some(Color(water_color)), + ..self + } + } + + /// Builder function to override the biome foliage color + const fn foliage(self, foliage_color: [u8; 3]) -> Biome { + Biome { + foliage_color: Some(Color(foliage_color)), + ..self + } + } + + /// Builder function to override the biome grass color + const fn grass(self, grass_color: [u8; 3]) -> Biome { + Biome { + grass_color: Some(Color(grass_color)), + ..self + } + } + + /// Builder function to set a grass color modifier + const fn modify(self, grass_color_modifier: BiomeGrassColorModifier) -> Biome { + Biome { + grass_color_modifier: Some(grass_color_modifier), + ..self + } + } + + /// Decodes a temperature or downfall value from the storage format to + /// f32 for further calculation + fn decode(val: i8) -> f32 { + f32::from(val) / 20.0 + } + + /// Returns the biome's temperature decoded to its original float value + pub fn temp(&self) -> f32 { + Self::decode(self.temp) + } + + /// Returns the biome's downfall decoded to its original float value + pub fn downfall(&self) -> f32 { + Self::decode(self.downfall) + } +} + /// Used to look up standard Minecraft biome types #[derive(Debug)] pub struct BiomeTypes { @@ -154,7 +258,7 @@ impl Default for BiomeTypes { .map(|(k, v)| (String::from(*k), v)) .collect(); - for &(old, new) in biomes::BIOME_ALIASES.iter().rev() { + for &(old, new) in legacy_biomes::BIOME_ALIASES.iter().rev() { let biome = biome_map .get(new) .copied() @@ -164,7 +268,7 @@ impl Default for BiomeTypes { let legacy_biomes = (0..=255) .map(|index| { - let id = biomes::legacy_biome(index); + let id = legacy_biomes::legacy_biome(index); *biome_map.get(id).expect("Unknown legacy biome") }) .collect::>() From 7b98954c8092ac150a21f8c2073c33b1a2f422e0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 13:05:47 +0100 Subject: [PATCH 080/152] resource: add comments to generated file --- crates/resource/src/block_types.rs | 5 +++++ crates/resource/src/lib.rs | 4 +--- resource/generate.py | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 4cdc55c..53abd54 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -1,7 +1,12 @@ +//! Block type information +//! +//! This file is generated using resource/generate.py, do not edit + use enumflags2::make_bitflags; use super::*; +/// List if known block types and their properties pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ ( "acacia_button", diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index b499fbf..1afcc62 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -4,12 +4,10 @@ mod biomes; mod block_color; +mod block_types; mod legacy_biomes; mod legacy_block_types; -#[allow(clippy::missing_docs_in_private_items)] // Generated module -mod block_types; - use std::collections::HashMap; use enumflags2::{bitflags, BitFlags}; diff --git a/resource/generate.py b/resource/generate.py index 8064482..ab91324 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -14,10 +14,15 @@ with open(sys.argv[1]) as f: output = {} with open(sys.argv[2], 'w') as f: + print('//! Block type information', file=f); + print('//!', file=f); + print('//! This file is generated using resource/generate.py, do not edit', file=f); + print('', file=f) print('use enumflags2::make_bitflags;', file=f); print('', file=f) print('use super::*;', file=f) print('', file=f) + print('/// List if known block types and their properties', file=f); print('pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[', file=f) for name, info in colors.items(): From 8f408e78a0dabcb2cc0b0aa0295bdb6d24f1705f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 13:51:55 +0100 Subject: [PATCH 081/152] resource: codegen biome list --- crates/resource/src/biomes.rs | 246 ++++++++++++++++------------------ resource/README.md | 15 ++- resource/biomes.py | 70 ++++++++++ 3 files changed, 197 insertions(+), 134 deletions(-) create mode 100755 resource/biomes.py diff --git a/crates/resource/src/biomes.rs b/crates/resource/src/biomes.rs index d81a069..55c5e74 100644 --- a/crates/resource/src/biomes.rs +++ b/crates/resource/src/biomes.rs @@ -1,137 +1,117 @@ //! Biome data +//! +//! This file is generated using resource/biomes.py, do not edit use super::*; +use BiomeGrassColorModifier::*; -/// Standard biome specifications -pub const BIOMES: &[(&str, Biome)] = { - use BiomeGrassColorModifier::*; - - // Data extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn - - // We can't use floats in const functions, to temperature and downfall values - // are specified multipled by 100. The underscore is used in place of the decimal point - // of the original values. - - #[allow(clippy::zero_prefixed_literal)] - &[ - // Overworld - ( - "badlands", - Biome::new(2_00, 0_00) - .foliage([158, 129, 77]) - .grass([144, 129, 77]), - ), - ("bamboo_jungle", Biome::new(0_95, 0_90)), - ("beach", Biome::new(0_80, 0_40)), - ("birch_forest", Biome::new(0_60, 0_60)), - ( - "cherry_grove", - Biome::new(0_50, 0_80) - .water([93, 183, 239]) - .grass([182, 219, 97]) - .foliage([182, 219, 97]), - ), - ("cold_ocean", Biome::new(0_50, 0_50).water([61, 87, 214])), - ("dark_forest", Biome::new(0_70, 0_80).modify(DarkForest)), - ( - "deep_cold_ocean", - Biome::new(0_50, 0_50).water([61, 87, 214]), - ), - ("deep_dark", Biome::new(0_80, 0_40)), - ( - "deep_frozen_ocean", - Biome::new(0_50, 0_50).water([57, 56, 201]), - ), - ( - "deep_lukewarm_ocean", - Biome::new(0_50, 0_50).water([69, 173, 242]), - ), - ("deep_ocean", Biome::new(0_50, 0_50)), - ("desert", Biome::new(2_00, 0_00)), - ("dripstone_caves", Biome::new(0_80, 0_40)), - ( - "eroded_badlands", - Biome::new(2_00, 0_00) - .foliage([158, 129, 77]) - .grass([144, 129, 77]), - ), - ("flower_forest", Biome::new(0_70, 0_80)), - ("forest", Biome::new(0_70, 0_80)), - ("frozen_ocean", Biome::new(0_00, 0_50).water([57, 56, 201])), - ("frozen_peaks", Biome::new(-0_70, 0_90)), - ("frozen_river", Biome::new(0_00, 0_50).water([57, 56, 201])), - ("grove", Biome::new(-0_20, 0_80)), - ("ice_spikes", Biome::new(0_00, 0_50)), - ("jagged_peaks", Biome::new(-0_70, 0_90)), - ("jungle", Biome::new(0_95, 0_90)), - ( - "lukewarm_ocean", - Biome::new(0_50, 0_50).water([69, 173, 242]), - ), - ("lush_caves", Biome::new(0_50, 0_50)), - ( - "mangrove_swamp", - Biome::new(0_80, 0_90) - .water([58, 122, 106]) - .foliage([141, 177, 39]) - .modify(Swamp), - ), - ("meadow", Biome::new(0_50, 0_80).water([14, 78, 207])), - ("mushroom_fields", Biome::new(0_90, 1_00)), - ("ocean", Biome::new(0_50, 0_50)), - ("old_growth_birch_forest", Biome::new(0_60, 0_60)), - ("old_growth_pine_taiga", Biome::new(0_30, 0_80)), - ("old_growth_spruce_taiga", Biome::new(0_25, 0_80)), - ( - "pale_garden", - Biome::new(0_70, 0_80) - .water([118, 136, 157]) - .foliage([135, 141, 118]) - .grass([119, 130, 114]), - ), - ("plains", Biome::new(0_80, 0_40)), - ("river", Biome::new(0_50, 0_50)), - ("savanna", Biome::new(2_00, 0_00)), - ("savanna_plateau", Biome::new(2_00, 0_00)), - ("snowy_beach", Biome::new(0_05, 0_30).water([61, 87, 214])), - ("snowy_plains", Biome::new(0_00, 0_50)), - ("snowy_slopes", Biome::new(-0_30, 0_90)), - ("snowy_taiga", Biome::new(-0_50, 0_40).water([61, 87, 214])), - ("sparse_jungle", Biome::new(0_95, 0_80)), - ("stony_peaks", Biome::new(1_00, 0_30)), - ("stony_shore", Biome::new(0_20, 0_30)), - ("sunflower_plains", Biome::new(0_80, 0_40)), - ( - "swamp", - Biome::new(0_80, 0_90) - .water([97, 123, 100]) - .foliage([106, 112, 57]) - .modify(Swamp), - ), - ("taiga", Biome::new(0_25, 0_80)), - ("the_void", Biome::new(0_50, 0_50)), - ("warm_ocean", Biome::new(0_50, 0_50).water([67, 213, 238])), - ("windswept_forest", Biome::new(0_20, 0_30)), - ("windswept_gravelly_hills", Biome::new(0_20, 0_30)), - ("windswept_hills", Biome::new(0_20, 0_30)), - ("windswept_savanna", Biome::new(2_00, 0_00)), - ( - "wooded_badlands", - Biome::new(2_00, 0_00) - .foliage([158, 129, 77]) - .grass([144, 129, 77]), - ), - // Nether - ("basalt_deltas", Biome::new(2_00, 0_00)), - ("crimson_forest", Biome::new(2_00, 0_00)), - ("nether_wastes", Biome::new(2_00, 0_00)), - ("soul_sand_valley", Biome::new(2_00, 0_00)), - ("warped_forest", Biome::new(2_00, 0_00)), - // End - ("end_barrens", Biome::new(0_50, 0_50)), - ("end_highlands", Biome::new(0_50, 0_50)), - ("end_midlands", Biome::new(0_50, 0_50)), - ("small_end_islands", Biome::new(0_50, 0_50)), - ("the_end", Biome::new(0_50, 0_50)), - ] -}; +/// List if known biomes and their properties +pub const BIOMES: &[(&str, Biome)] = &[ + ( + "badlands", + Biome::new(200, 0) + .foliage([158, 129, 77]) + .grass([144, 129, 77]), + ), + ("bamboo_jungle", Biome::new(95, 90)), + ("basalt_deltas", Biome::new(200, 0)), + ("beach", Biome::new(80, 40)), + ("birch_forest", Biome::new(60, 60)), + ( + "cherry_grove", + Biome::new(50, 80) + .foliage([182, 219, 97]) + .grass([182, 219, 97]) + .water([93, 183, 239]), + ), + ("cold_ocean", Biome::new(50, 50).water([61, 87, 214])), + ("crimson_forest", Biome::new(200, 0)), + ("dark_forest", Biome::new(70, 80).modify(DarkForest)), + ("deep_cold_ocean", Biome::new(50, 50).water([61, 87, 214])), + ("deep_dark", Biome::new(80, 40)), + ("deep_frozen_ocean", Biome::new(50, 50).water([57, 56, 201])), + ( + "deep_lukewarm_ocean", + Biome::new(50, 50).water([69, 173, 242]), + ), + ("deep_ocean", Biome::new(50, 50)), + ("desert", Biome::new(200, 0)), + ("dripstone_caves", Biome::new(80, 40)), + ("end_barrens", Biome::new(50, 50)), + ("end_highlands", Biome::new(50, 50)), + ("end_midlands", Biome::new(50, 50)), + ( + "eroded_badlands", + Biome::new(200, 0) + .foliage([158, 129, 77]) + .grass([144, 129, 77]), + ), + ("flower_forest", Biome::new(70, 80)), + ("forest", Biome::new(70, 80)), + ("frozen_ocean", Biome::new(0, 50).water([57, 56, 201])), + ("frozen_peaks", Biome::new(-70, 90)), + ("frozen_river", Biome::new(0, 50).water([57, 56, 201])), + ("grove", Biome::new(-20, 80)), + ("ice_spikes", Biome::new(0, 50)), + ("jagged_peaks", Biome::new(-70, 90)), + ("jungle", Biome::new(95, 90)), + ("lukewarm_ocean", Biome::new(50, 50).water([69, 173, 242])), + ("lush_caves", Biome::new(50, 50)), + ( + "mangrove_swamp", + Biome::new(80, 90) + .foliage([141, 177, 39]) + .modify(Swamp) + .water([58, 122, 106]), + ), + ("meadow", Biome::new(50, 80).water([14, 78, 207])), + ("mushroom_fields", Biome::new(90, 100)), + ("nether_wastes", Biome::new(200, 0)), + ("ocean", Biome::new(50, 50)), + ("old_growth_birch_forest", Biome::new(60, 60)), + ("old_growth_pine_taiga", Biome::new(30, 80)), + ("old_growth_spruce_taiga", Biome::new(25, 80)), + ( + "pale_garden", + Biome::new(70, 80) + .foliage([135, 141, 118]) + .grass([119, 130, 114]) + .water([118, 136, 157]), + ), + ("plains", Biome::new(80, 40)), + ("river", Biome::new(50, 50)), + ("savanna", Biome::new(200, 0)), + ("savanna_plateau", Biome::new(200, 0)), + ("small_end_islands", Biome::new(50, 50)), + ("snowy_beach", Biome::new(5, 30).water([61, 87, 214])), + ("snowy_plains", Biome::new(0, 50)), + ("snowy_slopes", Biome::new(-30, 90)), + ("snowy_taiga", Biome::new(-50, 40).water([61, 87, 214])), + ("soul_sand_valley", Biome::new(200, 0)), + ("sparse_jungle", Biome::new(95, 80)), + ("stony_peaks", Biome::new(100, 30)), + ("stony_shore", Biome::new(20, 30)), + ("sunflower_plains", Biome::new(80, 40)), + ( + "swamp", + Biome::new(80, 90) + .foliage([106, 112, 57]) + .modify(Swamp) + .water([97, 123, 100]), + ), + ("taiga", Biome::new(25, 80)), + ("the_end", Biome::new(50, 50)), + ("the_void", Biome::new(50, 50)), + ("warm_ocean", Biome::new(50, 50).water([67, 213, 238])), + ("warped_forest", Biome::new(200, 0)), + ("windswept_forest", Biome::new(20, 30)), + ("windswept_gravelly_hills", Biome::new(20, 30)), + ("windswept_hills", Biome::new(20, 30)), + ("windswept_savanna", Biome::new(200, 0)), + ( + "wooded_badlands", + Biome::new(200, 0) + .foliage([158, 129, 77]) + .grass([144, 129, 77]), + ), +]; diff --git a/resource/README.md b/resource/README.md index ab9d5ea..12302ec 100644 --- a/resource/README.md +++ b/resource/README.md @@ -11,13 +11,15 @@ work. - `extract.py`: Takes the block type information from `blocks.json` and texture data from an unpacked Minecraft JAR, storing the result in `colors.json` - `generate.py`: Generates `block_types.rs` from `colors.json` +- `biomes.py`: Generates `biomes.rs` from biome JSON files of an unpacked + Minecraft JAR - `sign_textures.py`: Generates all needed sign graphics from Minecraft assets In addition to these scripts, the JSON processor *jq* is a useful tool to work with MinedMap's resource metadata. -## How to add support for block IDs of a new Minecraft version +## How to add support for block IDs and biomes of a new Minecraft version 1. Download the Minecraft version you want to support as well as the previous version currently supported by MinedMap. You can use the Minecraft launcher @@ -69,6 +71,17 @@ with MinedMap's resource metadata. cargo fmt --all ``` +8. Update the source code for new biome data: + + ```sh + ./biomes.py data/new ../crates/resource/src/biomes.rs + cargo fmt --all + ``` + + After regenerating, check if only new biomes were added. If entries + got removed, biomes may have been renamed or merged, requiring updates + to the alias list in `crates/resource/src/legacy_biomes.rs`. + After the update, the new version should be tested with old savegames (both before and after migration by the new version) as well as newly generated worlds. Use creative mode to add the new block types to your test world. diff --git a/resource/biomes.py b/resource/biomes.py new file mode 100755 index 0000000..4e3bc51 --- /dev/null +++ b/resource/biomes.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import json +import os +import sys + + +if len(sys.argv) != 3: + sys.exit('Usage: biomes.py ') + +biomes = {} + +for file in os.scandir(os.path.join(sys.argv[1], 'data/minecraft/worldgen/biome')): + (name, ext) = os.path.splitext(file.name) + if ext != '.json': + continue + with open(file) as f: + data = json.load(f) + biomes[name] = { + 'downfall': data['downfall'], + 'temperature': data['temperature'], + 'foliage_color': data['effects'].get('foliage_color'), + 'grass_color': data['effects'].get('grass_color'), + 'grass_color_modifier': data['effects'].get('grass_color_modifier'), + 'water_color': data['effects'].get('water_color'), + } + +def color(v): + return f'[{v>>16}, {(v>>8)&0xff}, {v&0xff}]' + +# Converts the snake_case grass color modifier to CamelCase +def modify(v): + return ''.join([s.capitalize() for s in v.split('_')]) + +def gen_biome(name, info, f): + temp = round(100*info['temperature']) + downfall = round(100*info['downfall']) + foliage_color = info['foliage_color'] + grass_color = info['grass_color'] + grass_color_modifier = info['grass_color_modifier'] + water_color = info['water_color'] + + print(f'\t("{name}", Biome::new({temp}, {downfall})', file=f) + + if foliage_color is not None: + print(f'\t\t.foliage({color(foliage_color)})', file=f) + if grass_color is not None: + print(f'\t\t.grass({color(grass_color)})', file=f) + if grass_color_modifier is not None: + print(f'\t\t.modify({modify(grass_color_modifier)})', file=f) + if water_color is not None and water_color != 0x3f76e4: + print(f'\t\t.water({color(water_color)})', file=f) + + print('\t),', file=f) + +with open(sys.argv[2], 'w') as f: + print('//! Biome data', file=f); + print('//!', file=f); + print('//! This file is generated using resource/biomes.py, do not edit', file=f); + print('', file=f) + print('use super::*;', file=f) + print('use BiomeGrassColorModifier::*;', file=f) + print('', file=f) + print('/// List if known biomes and their properties', file=f); + print('pub const BIOMES: &[(&str, Biome)] = &[', file=f) + + for name in sorted(biomes): + gen_biome(name, biomes[name], f) + + print('];', file=f) From 00237101f26407f4d29fd497aa621f27cad1833c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 31 Dec 2024 12:15:45 +0100 Subject: [PATCH 082/152] README.md: update for 1.21.4 support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2312c03..4c684f9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ * Render beautiful maps of your [Minecraft](https://minecraft.net/) worlds! * Put them on a webserver and view them in your browser! -* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21.4 (no mod installation required!) * Illumination layer: the world at night * Fast: create a full map for a huge 3GB savegame in less than 5 minutes in single-threaded operation * Multi-threading support: pass `-j N` to the renderer to use `N` parallel threads for generation From 941cd16337ee153407139fec73d78f964339a0d7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Jan 2025 13:41:56 +0100 Subject: [PATCH 083/152] minedmap-resource 0.5.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff64b60..b7a3740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -610,7 +610,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.4.0" +version = "0.5.0" dependencies = [ "enumflags2", "glam", diff --git a/Cargo.toml b/Cargo.toml index ddf24ba..ad65c83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ image = { version = "0.25.1", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.4.0", path = "crates/resource" } +minedmap-resource = { version = "0.5.0", path = "crates/resource" } minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index de9b577..58e1da2 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.4.0" +version = "0.5.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From 650cd23198db1ba38d84510519e9cc3a82ae6b1f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Jan 2025 13:42:11 +0100 Subject: [PATCH 084/152] minedmap 2.3.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c7c159..ab33e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.3.0] - 2025-01-02 + - Added support for Minecraft 1.21.4 block types - Added support for Minecraft 1.21.4 Pale Garden biome - viewer: added images for pale oak signs @@ -99,7 +101,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.2.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.3.0...HEAD +[2.3.0]: https://github.com/neocturne/MinedMap/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/neocturne/MinedMap/compare/v2.1.1...v2.2.0 [2.1.1]: https://github.com/neocturne/MinedMap/compare/v2.1.0...v2.1.1 [2.1.0]: https://github.com/neocturne/MinedMap/compare/v2.0.2...v2.1.0 diff --git a/Cargo.lock b/Cargo.lock index b7a3740..c18929f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -567,7 +567,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" -version = "2.2.0" +version = "2.3.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index ad65c83..e2f36b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.2.0" +version = "2.3.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From 7f329ac8e73ef7f7d13ff842026b5397b7fa8f0a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 20:30:17 +0100 Subject: [PATCH 085/152] CHANGELOG.md: fix heading for previous release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab33e93..4c9847e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## [2.3.0] - 2025-01-02 +### Added + - Added support for Minecraft 1.21.4 block types - Added support for Minecraft 1.21.4 Pale Garden biome - viewer: added images for pale oak signs From 9375af8d54d13f40932579ba0e11fbabc0375bb8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 20:27:01 +0100 Subject: [PATCH 086/152] resource: impl Ord for Color Allow using Color in FormattedText. --- crates/resource/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index 1afcc62..fed9514 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -38,7 +38,7 @@ pub enum BlockFlag { } /// An RGB color with u8 components -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] pub struct Color(pub [u8; 3]); /// An RGB color with f32 components From ff6e28d381574fecc0a10466faf35c60a9efd756 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 21:16:41 +0100 Subject: [PATCH 087/152] world, viewer: fix sign text colors - Fix text colors for signs modified using dye - Fix text colors specified using `#rrggbb` CSS syntax in JSON text Only named colors specified via JSON text were working as intended. Dyed signs use different color names. The mapping of color names to values is now handled by the generator. Both the generator and the viewer must be updated for sign text colors to work. --- CHANGELOG.md | 11 ++++++ Cargo.lock | 64 ++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/core/common.rs | 2 +- src/world/json_text.rs | 89 ++++++++++++++++++++++++++++++++++++++++-- src/world/sign.rs | 29 +++++++++++++- viewer/MinedMap.js | 23 ++--------- 7 files changed, 192 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c9847e..aabf1f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## [Unreleased] - ReleaseDate +### Fixed + +- Fix text colors for signs modified using dye +- Fix text colors specified using `#rrggbb` CSS syntax in JSON text + +Only named colors specified via JSON text were working as intended. Dyed signs use different +color names. + +The mapping of color names to values is now handled by the generator. Both the generator and the +viewer must be updated for sign text colors to work. + ## [2.3.0] - 2025-01-02 ### Added diff --git a/Cargo.lock b/Cargo.lock index c18929f..90a9b7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -584,6 +584,7 @@ dependencies = [ "minedmap-types", "num-integer", "num_cpus", + "phf", "rayon", "regex", "rustc-hash", @@ -717,6 +718,48 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -766,6 +809,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "rayon" version = "1.10.0" @@ -923,6 +981,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" diff --git a/Cargo.toml b/Cargo.toml index e2f36b6..287ac4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ minedmap-resource = { version = "0.5.0", path = "crates/resource" } minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" +phf = { version = "0.11.2", features = ["macros"] } rayon = "1.7.0" regex = "1.10.2" rustc-hash = "2.0.0" diff --git a/src/core/common.rs b/src/core/common.rs index 3dd01cf..be6d28a 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -46,7 +46,7 @@ pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap processed entity data version number /// /// Increase when entity collection changes bacause of code changes. -pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); /// Coordinate pair of a generated tile /// diff --git a/src/world/json_text.rs b/src/world/json_text.rs index a153179..fa18527 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -1,7 +1,8 @@ //! Newtype and helper methods for handling Minecraft Raw JSON Text -use std::{collections::VecDeque, fmt::Display, sync::Arc}; +use std::{collections::VecDeque, fmt::Display}; +use minedmap_resource::Color; use serde::{Deserialize, Serialize}; /// A span of formatted text @@ -17,8 +18,8 @@ pub struct FormattedText { /// Text content pub text: String, /// Text color - #[serde(skip_serializing_if = "Option::is_none")] - pub color: Option>, + #[serde(skip_serializing_if = "Option::is_none", with = "json_color")] + pub color: Option, /// Bold formatting #[serde(skip_serializing_if = "Option::is_none")] pub bold: Option, @@ -41,7 +42,7 @@ impl FormattedText { pub fn inherit(self, parent: &Self) -> Self { FormattedText { text: self.text, - color: self.color.or_else(|| parent.color.clone()), + color: self.color.or(parent.color), bold: self.bold.or(parent.bold), italic: self.italic.or(parent.italic), underlined: self.underlined.or(parent.underlined), @@ -175,3 +176,83 @@ impl JSONText { serde_json::from_str(&self.0).unwrap_or_default() } } + +mod json_color { + //! Helpers for serializing and deserializing [FormattedText](super::FormattedText) colors + + use minedmap_resource::Color; + use serde::{ + de::{self, Visitor}, + ser::Error as _, + Deserializer, Serializer, + }; + + /// Named JSON text colors + static COLORS: phf::Map<&'static str, Color> = phf::phf_map! { + "black" => Color([0x00, 0x00, 0x00]), + "dark_blue" => Color([0x00, 0x00, 0xAA]), + "dark_green" => Color([0x00, 0xAA, 0x00]), + "dark_aqua" => Color([0x00, 0xAA, 0xAA]), + "dark_red" => Color([0xAA, 0x00, 0x00]), + "dark_purple" => Color([0xAA, 0x00, 0xAA]), + "gold" => Color([0xFF, 0xAA, 0x00]), + "gray" => Color([0xAA, 0xAA, 0xAA]), + "dark_gray" => Color([0x55, 0x55, 0x55]), + "blue" => Color([0x55, 0x55, 0xFF]), + "green" => Color([0x55, 0xFF, 0x55]), + "aqua" => Color([0x55, 0xFF, 0xFF]), + "red" => Color([0xFF, 0x55, 0x55]), + "light_purple" => Color([0xFF, 0x55, 0xFF]), + "yellow" => Color([0xFF, 0xFF, 0x55]), + "white" => Color([0xFF, 0xFF, 0xFF]), + }; + + /// serde serialize function for [FormattedText::color](super::FormattedText::color) + pub fn serialize(color: &Option, serializer: S) -> Result + where + S: Serializer, + { + let &Some(color) = color else { + return Err(S::Error::custom("serialize called for None sign color")); + }; + + let text = format!("#{:02x}{:02x}{:02x}", color.0[0], color.0[1], color.0[2]); + serializer.serialize_str(&text) + } + + /// serde [Visitor] for use by [deserialize] + struct ColorVisitor; + + impl Visitor<'_> for ColorVisitor { + type Value = Option; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a string representing a color") + } + + fn visit_str(self, color: &str) -> Result + where + E: de::Error, + { + if let Some(hex) = color.strip_prefix("#") { + if let Ok(value) = u32::from_str_radix(hex, 16) { + return Ok(Some(Color([ + (value >> 16) as u8, + (value >> 8) as u8, + value as u8, + ]))); + } + } + + Ok(COLORS.get(color).copied()) + } + } + + /// serde deserialize function for [FormattedText::color](super::FormattedText::color) + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(ColorVisitor) + } +} diff --git a/src/world/sign.rs b/src/world/sign.rs index 57b741a..eff319f 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -1,7 +1,8 @@ //! Processing of sign text -use std::{fmt::Display, sync::Arc}; +use std::fmt::Display; +use minedmap_resource::Color; use serde::{Deserialize, Serialize}; use super::{ @@ -23,10 +24,34 @@ pub struct RawSignText<'a> { pub color: Option<&'a str>, } +/// The color to use for signs without a color attribute ("black") +const DEFAULT_COLOR: Color = Color([0, 0, 0]); + +/// Map of text colors associated with dyes (except for black) +static DYE_COLORS: phf::Map<&'static str, Color> = phf::phf_map! { + "white" => Color([255, 255, 255]), + "orange" => Color([255, 104, 31]), + "magenta" => Color([255, 0, 255]), + "light_blue" => Color([154, 192, 205]), + "yellow" => Color([255, 255, 0]), + "lime" => Color([191, 255, 0]), + "pink" => Color([255, 105, 180]), + "gray" => Color([128, 128, 128]), + "light_gray" => Color([211, 211, 211]), + "cyan" => Color([0, 255, 255]), + "purple" => Color([160, 32, 240]), + "blue" => Color([0, 0, 255]), + "brown" => Color([139, 69, 19]), + "green" => Color([0, 255, 0]), + "red" => Color([255, 0, 0]), +}; + impl RawSignText<'_> { /// Decodes the [RawSignText] into a [SignText] pub fn decode(&self) -> SignText { - let color = self.color.map(|c| Arc::new(c.to_owned())); + let color = self + .color + .map(|c| DYE_COLORS.get(c).copied().unwrap_or(DEFAULT_COLOR)); let parent = FormattedText { color, ..Default::default() diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index e784eec..cfcccf1 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -153,25 +153,6 @@ const parseHash = function () { return args; } -const colors = { - black: '#000000', - dark_blue: '#0000AA', - dark_green: '#00AA00', - dark_aqua: '#00AAAA', - dark_red: '#AA0000', - dark_purple: '#AA00AA', - gold: '#FFAA00', - gray: '#AAAAAA', - dark_gray: '#555555', - blue: '#5555FF', - green: '#55FF55', - aqua: '#55FFFF', - red: '#FF5555', - light_purple: '#FF55FF', - yellow: '#FFFF55', - white: '#FFFFFF', -}; - function formatSignLine(line) { const el = document.createElement('span'); el.style.whiteSpace = 'pre'; @@ -180,7 +161,9 @@ function formatSignLine(line) { const child = document.createElement('span'); child.textContent = span.text; - const color = colors[span.color ?? 'black'] || colors['black']; + let color = span.color ?? ''; + if (color[0] !== '#') + color = '#000000'; if (span.bold) child.style.fontWeight = 'bold'; From a67bdb3b67dc1b576b9aeb77bd93605955da21ab Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 21:25:20 +0100 Subject: [PATCH 088/152] minedmap-resource 0.6.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90a9b7a..e616496 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,7 +611,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.5.0" +version = "0.6.0" dependencies = [ "enumflags2", "glam", diff --git a/Cargo.toml b/Cargo.toml index 287ac4c..f3a3798 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ image = { version = "0.25.1", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.5.0", path = "crates/resource" } +minedmap-resource = { version = "0.6.0", path = "crates/resource" } minedmap-types = { version = "0.1.2", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 58e1da2..4e0d512 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.5.0" +version = "0.6.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From f9954d1ce4e8dd25802c64bd36b6baccad0e8a42 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 21:25:29 +0100 Subject: [PATCH 089/152] minedmap 2.3.1 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aabf1f1..4a18819 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.3.1] - 2025-01-06 + ### Fixed - Fix text colors for signs modified using dye @@ -114,7 +116,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.3.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.3.1...HEAD +[2.3.1]: https://github.com/neocturne/MinedMap/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/neocturne/MinedMap/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/neocturne/MinedMap/compare/v2.1.1...v2.2.0 [2.1.1]: https://github.com/neocturne/MinedMap/compare/v2.1.0...v2.1.1 diff --git a/Cargo.lock b/Cargo.lock index e616496..cbd4110 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -567,7 +567,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" -version = "2.3.0" +version = "2.3.1" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index f3a3798..6a6a300 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.3.0" +version = "2.3.1" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From b9cd94b235523d982d5a35895aa27f2b8d54a7f5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 6 Jan 2025 22:31:56 +0100 Subject: [PATCH 090/152] CHANGELOG.md: remove reference to Minecraft internals Remove a sentence that refers to internal color names, as the information is more confusing than helpful in a user-facing changlog. --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a18819..1b5dd97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,8 +9,7 @@ - Fix text colors for signs modified using dye - Fix text colors specified using `#rrggbb` CSS syntax in JSON text -Only named colors specified via JSON text were working as intended. Dyed signs use different -color names. +Only named colors specified via JSON text were working as intended. The mapping of color names to values is now handled by the generator. Both the generator and the viewer must be updated for sign text colors to work. From 52572a9e81cef19d8427a54a538aaf55891e2af0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 9 Jan 2025 20:55:37 +0100 Subject: [PATCH 091/152] Update dependencies --- Cargo.lock | 68 ++++++++++++++++++++--------------------- crates/types/Cargo.toml | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbd4110..87d4135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,9 +149,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -172,9 +172,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.23" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck", "proc-macro2", @@ -484,9 +484,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] @@ -520,9 +520,9 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libz-ng-sys" -version = "1.1.20" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0f7295a34685977acb2e8cc8b08ee4a8dffd6cf278eeccddbe1ed55ba815d5" +checksum = "7cee1488e961a80d172564fd6fcda11d8a4ac6672c06fe008e9213fa60520c2b" dependencies = [ "cmake", "libc", @@ -530,9 +530,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "lock_api" @@ -720,9 +720,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -730,9 +730,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand", @@ -740,9 +740,9 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", @@ -753,18 +753,18 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -896,9 +896,9 @@ checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags 2.6.0", "errno", @@ -950,9 +950,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -983,9 +983,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" @@ -1010,9 +1010,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.93" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -1041,9 +1041,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.42.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "parking_lot", diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 6a81414..1146195 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -8,5 +8,5 @@ readme.workspace = true repository.workspace = true [dependencies] -itertools = "0.13.0" +itertools = "0.14.0" serde = { version = "1.0.183", features = ["derive"] } From 28a191a23af16a6e82c62a4ac4a58051203ef900 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 9 Jan 2025 21:09:48 +0100 Subject: [PATCH 092/152] resource: ignore array size clippy warning The const is used only once, so there is no reason not to inline it. --- crates/resource/src/legacy_block_types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/resource/src/legacy_block_types.rs b/crates/resource/src/legacy_block_types.rs index c027ac3..0c4814d 100644 --- a/crates/resource/src/legacy_block_types.rs +++ b/crates/resource/src/legacy_block_types.rs @@ -13,6 +13,7 @@ const DEF: &str = "air"; const EMPTY: [&str; 16] = simple(DEF); /// Mapping from each numeric block type and damage/subtype ID to new string ID +#[allow(clippy::large_const_arrays)] pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ /* 0 */ simple("air"), From c23b53a8c3de7c0eefb6a3b0775ea15b8c24bbcc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 01:24:58 +0100 Subject: [PATCH 093/152] core, viewer: add support for WebP output WebP can be selected by passing `--image-format webp` on the command line. For typical Minecraft worlds, this results in a size reduction of 10-15% without increasing processing time. --- CHANGELOG.md | 4 ++++ Cargo.lock | 17 +++++++++++++++++ Cargo.toml | 2 +- README.md | 11 ++++++++++- src/core/common.rs | 31 ++++++++++++++++++++++++++++++- src/core/metadata_writer.rs | 3 +++ src/core/mod.rs | 5 ++++- src/core/region_processor.rs | 5 ++++- src/core/tile_mipmapper.rs | 2 +- src/core/tile_renderer.rs | 2 +- viewer/MinedMap.js | 10 ++++++---- 11 files changed, 81 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5dd97..dbd71f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added support for rendering tiles WebP format using the `--image-format` option + ## [2.3.1] - 2025-01-06 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 87d4135..970c1be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,10 +461,21 @@ checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", "byteorder-lite", + "image-webp", "num-traits", "png", ] +[[package]] +name = "image-webp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + [[package]] name = "indexmap" version = "2.7.0" @@ -800,6 +811,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quote" version = "1.0.38" diff --git a/Cargo.toml b/Cargo.toml index 6a6a300..c4bfdcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ enum-map = "2.7.3" fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" -image = { version = "0.25.1", default-features = false, features = ["png"] } +image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } diff --git a/README.md b/README.md index 4c684f9..1ea4856 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,18 @@ a proper webserver like [nginx](https://nginx.org/) or upload the viewer togethe the generated map files to public webspace to make the map available to others. If you are uploading the directory to a remote webserver, you do not need to upload the -`/data/processed` directory, as that is only used locally to allow processing +`/data/processed` directory, as it is only used locally to allow processing updates more quickly. +### Image formats + +MinedMap renders map tiles as PNG by default. Pass `--image-format webp` to select +WebP instead. For typical Minecraft worlds, using WebP reduces file sizes by 10-15% +without increasing processing time. + +MinedMap always uses lossless compression for tile images, regardless of the +image format. + ### Signs ![Sign screenshot](https://raw.githubusercontent.com/neocturne/MinedMap/e5d9c813ba3118d04dc7e52e3dc6f48808a69120/docs/images/signs.png) diff --git a/src/core/common.rs b/src/core/common.rs index be6d28a..b933dcd 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -7,6 +7,7 @@ use std::{ }; use anyhow::{Context, Result}; +use clap::ValueEnum; use indexmap::IndexSet; use regex::{Regex, RegexSet}; use serde::{Deserialize, Serialize}; @@ -150,6 +151,8 @@ pub struct Config { pub viewer_info_path: PathBuf, /// Path of viewer entities file pub viewer_entities_path: PathBuf, + /// Format of generated map tiles + pub image_format: ImageFormat, /// Sign text filter patterns pub sign_patterns: RegexSet, /// Sign text transformation pattern @@ -189,6 +192,7 @@ impl Config { entities_path_final, viewer_info_path, viewer_entities_path, + image_format: args.image_format, sign_patterns, sign_transforms, }) @@ -264,14 +268,39 @@ impl Config { [&self.output_dir, Path::new(&dir)].iter().collect() } + /// Returns the file extension for the configured image format + pub fn tile_extension(&self) -> &'static str { + match self.image_format { + ImageFormat::Png => "png", + ImageFormat::Webp => "webp", + } + } + /// Returns the configurured image format for the image library + pub fn tile_image_format(&self) -> image::ImageFormat { + match self.image_format { + ImageFormat::Png => image::ImageFormat::Png, + ImageFormat::Webp => image::ImageFormat::WebP, + } + } + /// Constructs the path of an output tile image pub fn tile_path(&self, kind: TileKind, level: usize, coords: TileCoords) -> PathBuf { - let filename = coord_filename(coords, "png"); + let filename = coord_filename(coords, self.tile_extension()); let dir = self.tile_dir(kind, level); [Path::new(&dir), Path::new(&filename)].iter().collect() } } +/// Format of generated map tiles +#[derive(Debug, Clone, Copy, Default, ValueEnum)] +pub enum ImageFormat { + /// Generate PNG images + #[default] + Png, + /// Generate WebP images + Webp, +} + /// Copies a chunk image into a region tile pub fn overlay_chunk(image: &mut I, chunk: &J, coords: ChunkCoords) where diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index 0ea1f65..92d8566 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -61,6 +61,8 @@ struct Metadata<'t> { spawn: Spawn, /// Enabled MinedMap features features: Features, + /// Format of generated map tiles + tile_extension: &'static str, } /// Viewer entity JSON data structure @@ -205,6 +207,7 @@ impl<'a> MetadataWriter<'a> { mipmaps: Vec::new(), spawn: Self::spawn(&level_dat), features, + tile_extension: self.config.tile_extension(), }; for tile_map in self.tiles.iter() { diff --git a/src/core/mod.rs b/src/core/mod.rs index f552ffa..5832379 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -16,7 +16,7 @@ use anyhow::{Context, Result}; use clap::Parser; use git_version::git_version; -use common::Config; +use common::{Config, ImageFormat}; use metadata_writer::MetadataWriter; use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; @@ -47,6 +47,9 @@ pub struct Args { /// Enable verbose messages #[arg(short, long)] pub verbose: bool, + /// Format of generated map tiles + #[arg(long, value_enum, default_value_t)] + pub image_format: ImageFormat, /// Prefix for text of signs to show on the map #[arg(long)] pub sign_prefix: Vec, diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index ce2d060..e448f5e 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -79,6 +79,8 @@ struct SingleRegionProcessor<'a> { lightmap: image::GrayAlphaImage, /// Processed entity intermediate data entities: ProcessedEntities, + /// Format of generated map tiles + image_format: image::ImageFormat, /// True if any unknown block or biome types were encountered during processing has_unknown: bool, } @@ -127,6 +129,7 @@ impl<'a> SingleRegionProcessor<'a> { processed_region, lightmap, entities, + image_format: processor.config.tile_image_format(), has_unknown: false, }) } @@ -179,7 +182,7 @@ impl<'a> SingleRegionProcessor<'a> { self.input_timestamp, |file| { self.lightmap - .write_to(file, image::ImageFormat::Png) + .write_to(file, self.image_format) .context("Failed to save image") }, ) diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index d7e54a9..2eda0e9 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -144,7 +144,7 @@ where } image - .write_to(file, image::ImageFormat::Png) + .write_to(file, self.config.tile_image_format()) .context("Failed to save image") } } diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 09ad8a1..a972b78 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -304,7 +304,7 @@ impl<'a> TileRenderer<'a> { processed_timestamp, |file| { image - .write_to(file, image::ImageFormat::Png) + .write_to(file, self.config.tile_image_format()) .context("Failed to save image") }, )?; diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index cfcccf1..61188b1 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -73,7 +73,7 @@ function signIcon(material, kind) { } const MinedMapLayer = L.TileLayer.extend({ - initialize: function (mipmaps, layer) { + initialize: function (mipmaps, layer, tile_extension) { L.TileLayer.prototype.initialize.call(this, '', { detectRetina: true, tileSize: 512, @@ -88,6 +88,7 @@ const MinedMapLayer = L.TileLayer.extend({ this.mipmaps = mipmaps; this.layer = layer; + this.ext = tile_extension; }, createTile: function (coords, done) { @@ -112,7 +113,7 @@ const MinedMapLayer = L.TileLayer.extend({ return L.Util.emptyImageUrl; - return 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; + return `data/${this.layer}/${z}/r.${coords.x}.${coords.y}.${this.ext}`; }, }); @@ -332,6 +333,7 @@ window.createMap = function () { const res = await response.json(); const {mipmaps, spawn} = res; const features = res.features || {}; + const tile_extension = res.tile_extension || 'png'; const updateParams = function () { const args = parseHash(); @@ -369,10 +371,10 @@ window.createMap = function () { const overlayMaps = {}; - const mapLayer = new MinedMapLayer(mipmaps, 'map'); + const mapLayer = new MinedMapLayer(mipmaps, 'map', tile_extension); mapLayer.addTo(map); - const lightLayer = new MinedMapLayer(mipmaps, 'light'); + const lightLayer = new MinedMapLayer(mipmaps, 'light', tile_extension); overlayMaps['Illumination'] = lightLayer; if (params.light) map.addLayer(lightLayer); From 6763e2b4ec8ac8c02f6256f9619983c01157ac05 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 01:42:42 +0100 Subject: [PATCH 094/152] Update dependencies --- Cargo.lock | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 970c1be..e902fc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,9 +125,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "bytemuck" @@ -313,6 +313,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.10" @@ -557,9 +567,12 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" +dependencies = [ + "value-bag", +] [[package]] name = "lru" @@ -867,7 +880,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", ] [[package]] @@ -917,7 +930,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", @@ -965,6 +978,15 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + [[package]] name = "serde_json" version = "1.0.135" @@ -1026,10 +1048,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "syn" -version = "2.0.95" +name = "sval" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" + +[[package]] +name = "sval_buffer" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" +dependencies = [ + "serde", + "sval", + "sval_nested", +] + +[[package]] +name = "syn" +version = "2.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1124,6 +1224,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + [[package]] name = "unicode-ident" version = "1.0.14" @@ -1142,6 +1248,42 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" +dependencies = [ + "erased-serde", + "serde", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "winapi" version = "0.3.9" From a2f0ad401d967e2ab56f4ce7ee2c5cccf045dc40 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 01:51:35 +0100 Subject: [PATCH 095/152] CHANGELOG.md: fix missing word --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbd71f8..c1bd945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Added -- Added support for rendering tiles WebP format using the `--image-format` option +- Added support for rendering tiles in WebP format using the `--image-format` option ## [2.3.1] - 2025-01-06 From 0bf1d46aad47fd184636f57b636104c91bd727b6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 01:53:05 +0100 Subject: [PATCH 096/152] minedmap-types 0.1.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/nbt/Cargo.toml | 2 +- crates/types/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e902fc1..9aeb667 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,7 +644,7 @@ dependencies = [ [[package]] name = "minedmap-types" -version = "0.1.3" +version = "0.1.4" dependencies = [ "itertools", "serde", diff --git a/Cargo.toml b/Cargo.toml index c4bfdcb..a143c78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } -minedmap-types = { version = "0.1.2", path = "crates/types" } +minedmap-types = { version = "0.1.4", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" phf = { version = "0.11.2", features = ["macros"] } diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index 2c817c6..9f815da 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -12,7 +12,7 @@ anyhow = "1.0.75" bytemuck = "1.13.1" fastnbt = "2.4.4" flate2 = "1.0.27" -minedmap-types = { version = "0.1.2", path = "../types" } +minedmap-types = { version = "0.1.4", path = "../types" } serde = "1.0.183" [features] diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 1146195..c5bd47e 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-types" -version = "0.1.3" +version = "0.1.4" description = "Common types used by several MinedMap crates" edition.workspace = true license.workspace = true From 561a1e6577a48663224bd7c30352d324a4e91b83 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 01:54:53 +0100 Subject: [PATCH 097/152] minedmap 2.4.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1bd945..e75a75b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.4.0] - 2025-01-11 + ### Added - Added support for rendering tiles in WebP format using the `--image-format` option @@ -119,7 +121,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.3.1...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.4.0...HEAD +[2.4.0]: https://github.com/neocturne/MinedMap/compare/v2.3.1...v2.4.0 [2.3.1]: https://github.com/neocturne/MinedMap/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/neocturne/MinedMap/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/neocturne/MinedMap/compare/v2.1.1...v2.2.0 diff --git a/Cargo.lock b/Cargo.lock index 9aeb667..5b6de78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,7 +591,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" -version = "2.3.1" +version = "2.4.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index a143c78..2412edb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.3.1" +version = "2.4.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From d7fc95c950e4f211785bdbfcd6364f60e9085763 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Jan 2025 02:10:00 +0100 Subject: [PATCH 098/152] README.md: fix size reduction estimate for WebP tiles I accidentally measured the output size including the `processed` directory for the previous numbers. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ea4856..7d60f78 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ updates more quickly. ### Image formats MinedMap renders map tiles as PNG by default. Pass `--image-format webp` to select -WebP instead. For typical Minecraft worlds, using WebP reduces file sizes by 10-15% +WebP instead. For typical Minecraft worlds, using WebP reduces file sizes by 20-25% without increasing processing time. MinedMap always uses lossless compression for tile images, regardless of the From a10151a4f37775d76150f03cc94dd32bd4c4705c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 11 Feb 2025 22:39:11 +0100 Subject: [PATCH 099/152] resource, world: implement fallback to plains for unknown biomes Closes #63 --- CHANGELOG.md | 6 ++++++ crates/resource/src/lib.rs | 11 +++++++++++ src/core/common.rs | 2 +- src/world/layer.rs | 16 ++++++++-------- src/world/section.rs | 20 +++++++++++--------- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e75a75b..7745ced 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] - ReleaseDate +### Changed + +- Unknown biome types (from not yet supported or modded versions of Minecraft) + will now use plains biome colors as a fallback instead of resulting in water, + grass and foliage blocks to be rendered as transparent pixels + ## [2.4.0] - 2025-01-11 ### Added diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index fed9514..a633d06 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -247,6 +247,8 @@ pub struct BiomeTypes { biome_map: HashMap, /// Array used to look up old numeric biome IDs legacy_biomes: Box<[&'static Biome; 256]>, + /// Fallback for unknown (new/modded) biomes + fallback_biome: &'static Biome, } impl Default for BiomeTypes { @@ -273,9 +275,12 @@ impl Default for BiomeTypes { .try_into() .unwrap(); + let fallback_biome = *biome_map.get("plains").expect("Plains biome undefined"); + Self { biome_map, legacy_biomes, + fallback_biome, } } } @@ -293,4 +298,10 @@ impl BiomeTypes { pub fn get_legacy(&self, id: u8) -> Option<&Biome> { Some(self.legacy_biomes[id as usize]) } + + /// Returns the fallback for unknown (new/modded) biomes + #[inline] + pub fn get_fallback(&self) -> &Biome { + self.fallback_biome + } } diff --git a/src/core/common.rs b/src/core/common.rs index b933dcd..edefcb3 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -25,7 +25,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(4); /// MinedMap map tile data version number /// diff --git a/src/world/layer.rs b/src/world/layer.rs index 0764711..e59593c 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -97,14 +97,14 @@ impl LayerEntry<'_> { if self.is_empty() { *self.block = Some(block_type.block_color); - if let Some(biome) = section.biomes.biome_at(section.y, coords)? { - let (biome_index, _) = biome_list.insert_full(*biome); - *self.biome = NonZeroU16::new( - (biome_index + 1) - .try_into() - .expect("biome index not in range"), - ); - } + + let biome = section.biomes.biome_at(section.y, coords)?; + let (biome_index, _) = biome_list.insert_full(*biome); + *self.biome = NonZeroU16::new( + (biome_index + 1) + .try_into() + .expect("biome index not in range"), + ); } if block_type.block_color.is(BlockFlag::Water) { diff --git a/src/world/section.rs b/src/world/section.rs index 7988fd5..845ddae 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -208,7 +208,7 @@ impl Section for SectionV0<'_> { /// Trait for common functions of [BiomesV1_18] and [BiomesV0] pub trait Biomes: Debug { /// Returns the [Biome] at a coordinate tuple inside the chunk - fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result>; + fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result<&Biome>; } /// Minecraft v1.18+ section biome data @@ -226,7 +226,7 @@ pub struct BiomesV1_18<'a> { /// to whole i64 values. biomes: Option<&'a [i64]>, /// Biome palette indexed by entries encoded in *biomes* - palette: Vec>, + palette: Vec<&'a Biome>, /// Number of bits used for each entry in *biomes* bits: u8, } @@ -253,12 +253,11 @@ impl<'a> BiomesV1_18<'a> { let palette_types = palette .iter() .map(|entry| { - let biome_type = biome_types.get(entry); - if biome_type.is_none() { + biome_types.get(entry).unwrap_or_else(|| { debug!("Unknown biome type: {}", entry); has_unknown = true; - } - biome_type + biome_types.get_fallback() + }) }) .collect(); @@ -295,7 +294,7 @@ impl<'a> BiomesV1_18<'a> { } impl Biomes for BiomesV1_18<'_> { - fn biome_at(&self, _section: SectionY, coords: SectionBlockCoords) -> Result> { + fn biome_at(&self, _section: SectionY, coords: SectionBlockCoords) -> Result<&Biome> { let index = self.palette_index_at(coords); Ok(*self .palette @@ -350,7 +349,7 @@ impl<'a> BiomesV0<'a> { } impl Biomes for BiomesV0<'_> { - fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result> { + fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result<&Biome> { let id = match self.data { BiomesV0Data::IntArrayV15(data) => { let LayerBlockCoords { x, z } = coords.xz; @@ -370,7 +369,10 @@ impl Biomes for BiomesV0<'_> { } BiomesV0Data::ByteArray(data) => data[coords.xz.offset()] as u8, }; - Ok(self.biome_types.get_legacy(id)) + Ok(self + .biome_types + .get_legacy(id) + .unwrap_or(self.biome_types.get_fallback())) } } From 0dd36a409a84438afd1e7bc768d5619ae3ff6053 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 11 Feb 2025 23:03:33 +0100 Subject: [PATCH 100/152] Update dependencies Signed-off-by: Matthias Schiffer --- Cargo.lock | 239 +++++++++++------------------------------------------ Cargo.toml | 2 +- 2 files changed, 50 insertions(+), 191 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b6de78..317eb46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,11 +73,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys", ] @@ -125,9 +126,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bytemuck" @@ -149,9 +150,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.7" +version = "1.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" dependencies = [ "jobserver", "libc", @@ -172,9 +173,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.26" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" dependencies = [ "clap_builder", "clap_derive", @@ -182,9 +183,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" dependencies = [ "anstream", "anstyle", @@ -195,9 +196,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", @@ -213,9 +214,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.52" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] @@ -288,9 +289,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" dependencies = [ "enumflags2_derive", "serde", @@ -298,9 +299,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", @@ -313,16 +314,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" -dependencies = [ - "serde", - "typeid", -] - [[package]] name = "errno" version = "0.3.10" @@ -478,9 +469,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" dependencies = [ "byteorder-lite", "quick-error", @@ -488,9 +479,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", @@ -567,18 +558,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6ea2a48c204030ee31a7d7fc72c93294c92fe87ecb1789881c9543516e1a0d" -dependencies = [ - "value-bag", -] +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "lru" -version = "0.12.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ "hashbrown", ] @@ -652,9 +640,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" dependencies = [ "adler2", "simd-adler32", @@ -709,9 +697,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "overload" @@ -817,9 +805,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -880,7 +868,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.8.0", ] [[package]] @@ -920,17 +908,17 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.8.0", "errno", "libc", "linux-raw-sys", @@ -939,9 +927,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "scopeguard" @@ -978,20 +966,11 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_fmt" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" -dependencies = [ - "serde", -] - [[package]] name = "serde_json" -version = "1.0.135" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -1047,89 +1026,11 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "sval" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6dc0f9830c49db20e73273ffae9b5240f63c42e515af1da1fceefb69fceafd8" - -[[package]] -name = "sval_buffer" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "429922f7ad43c0ef8fd7309e14d750e38899e32eb7e8da656ea169dd28ee212f" -dependencies = [ - "sval", - "sval_ref", -] - -[[package]] -name = "sval_dynamic" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f16ff5d839396c11a30019b659b0976348f3803db0626f736764c473b50ff4" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_fmt" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c01c27a80b6151b0557f9ccbe89c11db571dc5f68113690c1e028d7e974bae94" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_json" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0deef63c70da622b2a8069d8600cf4b05396459e665862e7bdb290fd6cf3f155" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_nested" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a39ce5976ae1feb814c35d290cf7cf8cd4f045782fe1548d6bc32e21f6156e9f" -dependencies = [ - "sval", - "sval_buffer", - "sval_ref", -] - -[[package]] -name = "sval_ref" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7c6ee3751795a728bc9316a092023529ffea1783499afbc5c66f5fabebb1fa" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_serde" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5572d0321b68109a343634e3a5d576bf131b82180c6c442dee06349dfc652a" -dependencies = [ - "serde", - "sval", - "sval_nested", -] - [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1224,17 +1125,11 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "typeid" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" - [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "utf8parse" @@ -1244,45 +1139,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "value-bag" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" -dependencies = [ - "value-bag-serde1", - "value-bag-sval2", -] - -[[package]] -name = "value-bag-serde1" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb773bd36fd59c7ca6e336c94454d9c66386416734817927ac93d81cb3c5b0b" -dependencies = [ - "erased-serde", - "serde", - "serde_fmt", -] - -[[package]] -name = "value-bag-sval2" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a916a702cac43a88694c97657d449775667bcd14b70419441d05b7fea4a83a" -dependencies = [ - "sval", - "sval_buffer", - "sval_dynamic", - "sval_fmt", - "sval_json", - "sval_ref", - "sval_serde", -] +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index 2412edb..b821d83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ futures-util = "0.3.28" git-version = "0.3.5" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = { version = "2.0.0", features = ["serde"] } -lru = "0.12.0" +lru = "0.13.0" minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } minedmap-types = { version = "0.1.4", path = "crates/types" } From d96bb727f72ed6536c183782dc8eb22df82ea7d3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 11 Feb 2025 23:04:08 +0100 Subject: [PATCH 101/152] ci: upgrade to upload-artifact v4 --- .github/workflows/MinedMap.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index c2e9961..cf75b68 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -27,7 +27,7 @@ jobs: cp -r viewer/* "$pkgdir"/ - name: 'Archive' - uses: 'actions/upload-artifact@v3' + uses: 'actions/upload-artifact@v4' with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-viewer' path: 'build/pkg' @@ -134,7 +134,7 @@ jobs: cp target/${{ matrix.target }}/release/minedmap${{ matrix.ext }} "$pkgdir"/ - name: 'Archive' - uses: 'actions/upload-artifact@v3' + uses: 'actions/upload-artifact@v4' with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' path: 'target/pkg' From 1d9be9a41cbfd665c41dbf5d7bfc2ba16584a224 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 12 Feb 2025 20:22:26 +0100 Subject: [PATCH 102/152] Add jemalloc and jemalloc-auto features Introduce the new features jemalloc (set jemalloc global allocator unconditionally) and jemalloc-auto (set jemalloc global allocator on musl-based targets to fix multithreaded performance, see [1]). Because cargo does not support target-specific features or feature defaults, the default is handled using a helper crate minedmap-default-alloc. [1] https://nickb.dev/blog/default-musl-allocator-considered-harmful-to-performance/ --- CHANGELOG.md | 22 ++++++++++++++++++++++ Cargo.lock | 28 ++++++++++++++++++++++++++++ Cargo.toml | 5 ++++- crates/default-alloc/Cargo.toml | 17 +++++++++++++++++ crates/default-alloc/src/lib.rs | 3 +++ src/main.rs | 3 +++ 6 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 crates/default-alloc/Cargo.toml create mode 100644 crates/default-alloc/src/lib.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7745ced..bec566e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added jemalloc support to fix performace on musl targets + + The global allocator can be switched to jemalloc by enabling the `jemalloc` + cargo feature now. This is not the default because it is not always faster + than the default system allocator; in particular, the glibc allocator has + slightly better performance in multithreaded mode. In addition, jemalloc + uses a bit more memory. + + In addition, the `jemalloc-auto` feature has been introduced, which is enabled + by default and sets the global allocator to jemalloc on platforms where it is + clearly advantageous. For now, this is only done on musl-based targets, as + musl's default allocator is very slow in multithreaded operation (which was + making higher thread counts like `-j8` basically useless due to 7-8x + slowdowns). With the new default, performance on musl is basically identical + to glibc. + + Note that some platforms like `msvc` are unsupported by jemalloc, and trying + to enable the `jemalloc` feature on these platforms may break the MinedMap + build or cause issues at runtime. + ### Changed - Unknown biome types (from not yet supported or modded versions of Minecraft) diff --git a/Cargo.lock b/Cargo.lock index 317eb46..eeaede2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,6 +591,7 @@ dependencies = [ "image", "indexmap", "lru", + "minedmap-default-alloc", "minedmap-nbt", "minedmap-resource", "minedmap-types", @@ -608,6 +609,13 @@ dependencies = [ "zstd", ] +[[package]] +name = "minedmap-default-alloc" +version = "0.1.0" +dependencies = [ + "tikv-jemallocator", +] + [[package]] name = "minedmap-nbt" version = "0.1.1" @@ -1057,6 +1065,26 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "tokio" version = "1.43.0" diff --git a/Cargo.toml b/Cargo.toml index b821d83..998de6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ git-version = "0.3.5" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.13.0" +minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } minedmap-types = { version = "0.1.4", path = "crates/types" } @@ -64,5 +65,7 @@ tracing-subscriber = "0.3.17" zstd = "0.13.0" [features] -default = ["zlib-ng"] +default = ["jemalloc-auto", "zlib-ng"] +jemalloc-auto = ["dep:minedmap-default-alloc"] +jemalloc = ["jemalloc-auto", "minedmap-default-alloc/jemalloc"] zlib-ng = ["minedmap-nbt/zlib-ng"] diff --git a/crates/default-alloc/Cargo.toml b/crates/default-alloc/Cargo.toml new file mode 100644 index 0000000..40f9e7e --- /dev/null +++ b/crates/default-alloc/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "minedmap-default-alloc" +version = "0.1.0" +description = "Helper crate for target-specific selection of global allocator default" +edition.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true + +[dependencies] +tikv-jemallocator = { version = "0.6.0", optional = true } + +[target.'cfg(target_env = "musl")'.dependencies] +tikv-jemallocator = "*" + +[features] +jemalloc = ["dep:tikv-jemallocator"] diff --git a/crates/default-alloc/src/lib.rs b/crates/default-alloc/src/lib.rs new file mode 100644 index 0000000..0797a5f --- /dev/null +++ b/crates/default-alloc/src/lib.rs @@ -0,0 +1,3 @@ +#[cfg(any(target_env = "musl", feature = "jemalloc"))] +#[global_allocator] +static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; diff --git a/src/main.rs b/src/main.rs index 31f2889..1f19a41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,9 @@ #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] +#[cfg(feature = "jemalloc-auto")] +extern crate minedmap_default_alloc; + mod core; mod io; mod util; From 971afea727210f9745a82b27a56d0c7fac2725d8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 21 Feb 2025 10:55:36 +0100 Subject: [PATCH 103/152] Fix new clippy warnings --- src/core/tile_renderer.rs | 2 +- src/util.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index a972b78..24af234 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -134,7 +134,7 @@ impl<'a> TileRenderer<'a> { /// Hashing the value as a single u32 is more efficient than hashing /// the tuple elements separately. fn biome_key((dx, dz, index): (i8, i8, u16)) -> u32 { - (dx as u8 as u32) | (dz as u8 as u32) << 8 | (index as u32) << 16 + (dx as u8 as u32) | ((dz as u8 as u32) << 8) | ((index as u32) << 16) } /// One quadrant of the kernel used to smooth biome edges diff --git a/src/util.rs b/src/util.rs index a128ef9..ed07ba5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -39,7 +39,9 @@ pub fn to_flat_coord( chunk: ChunkCoord, block: BlockCoord, ) -> i32 { - (region as i32) << (BLOCK_BITS + CHUNK_BITS) | ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32) + ((region as i32) << (BLOCK_BITS + CHUNK_BITS)) + | ((chunk.0 as i32) << BLOCK_BITS) + | (block.0 as i32) } /// Splits a flat (linear) coordinate into region, chunk and block numbers From 37126f69fcb9d6d5bbd31ad0a0b34fd522a733bb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Feb 2025 20:10:50 +0100 Subject: [PATCH 104/152] MetadataWriter: add fallback to level.dat_old Looking at inotify dumps, it appears like because of bad implementation choices, Minecraft's level.dat may not exist for a brief moment between moving the old file to level.dat_old and moving a new version into place. Add a fallback to level.dat_old, so generation will not fail if were unlucky enough to hit this moment. --- src/core/common.rs | 6 ++++++ src/core/metadata_writer.rs | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/common.rs b/src/core/common.rs index edefcb3..d311773 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -139,6 +139,8 @@ pub struct Config { pub region_dir: PathBuf, /// Path of input `level.dat` file pub level_dat_path: PathBuf, + /// Path of input `level.dat_old` file + pub level_dat_old_path: PathBuf, /// Base path for storage of rendered tile data pub output_dir: PathBuf, /// Path for storage of intermediate processed data files @@ -170,6 +172,9 @@ impl Config { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); + let level_dat_old_path = [&args.input_dir, Path::new("level.dat_old")] + .iter() + .collect(); let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect(); let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect(); @@ -186,6 +191,7 @@ impl Config { num_threads, region_dir, level_dat_path, + level_dat_old_path, output_dir: args.output_dir.clone(), processed_dir, entities_dir, diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index 92d8566..eb5f59f 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -124,7 +124,14 @@ impl<'a> MetadataWriter<'a> { /// Reads and deserializes the `level.dat` of the Minecraft save data fn read_level_dat(&self) -> Result { - crate::nbt::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") + let res = crate::nbt::data::from_file(&self.config.level_dat_path); + if res.is_err() { + if let Ok(level_dat_old) = crate::nbt::data::from_file(&self.config.level_dat_old_path) + { + return Ok(level_dat_old); + } + } + res.context("Failed to read level.dat") } /// Generates [Spawn] data from a [de::LevelDat] From c10e9e490203356633aa6fccc9240bf925147776 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Feb 2025 19:56:19 +0100 Subject: [PATCH 105/152] Implement watch mode --- CHANGELOG.md | 16 +++++ Cargo.lock | 170 +++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 2 + src/core/common.rs | 4 ++ src/core/mod.rs | 116 ++++++++++++++++++++++++++++--- 5 files changed, 292 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bec566e..e8fd052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ ### Added +- Added experimental watch mode + + Passing `--watch` will cause MinedMap to run continuously instead of exiting + after map generation, regenerating tiles whenever they change. + + `--watch-delay` can be used to configure the delay between detecting a change + and runing the map generation, also limiting how often the regeneration + happens. This defaults to `30s`; significantly smaller values probably don't + make sense because Minecraft writes out changes in batches anyways. + + Finally, `--jobs-initial` can be used to configure the number of parallel + generation threads for the initial cycle separately from the value used for + subsequent cycles after a change is detected (`-j`/`--jobs`). Subsequent + cycles usually need to regenerate only a small number of tiles, so setting + `--jobs` to a smaller value than `--jobs-initial` may be advantageous. + - Added jemalloc support to fix performace on musl targets The global allocator can be switched to jemalloc by enabling the `jemalloc` diff --git a/Cargo.lock b/Cargo.lock index eeaede2..039e940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -79,7 +79,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -321,7 +321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -345,6 +345,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + [[package]] name = "flate2" version = "1.0.35" @@ -362,6 +374,15 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futures-core" version = "0.3.31" @@ -454,6 +475,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "image" version = "0.25.5" @@ -488,6 +515,26 @@ dependencies = [ "serde", ] +[[package]] +name = "inotify" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +dependencies = [ + "bitflags 2.8.0", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -518,6 +565,26 @@ dependencies = [ "libc", ] +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -530,6 +597,17 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.8.0", + "libc", + "redox_syscall", +] + [[package]] name = "libz-ng-sys" version = "1.1.21" @@ -588,6 +666,7 @@ dependencies = [ "fastnbt", "futures-util", "git-version", + "humantime", "image", "indexmap", "lru", @@ -595,6 +674,7 @@ dependencies = [ "minedmap-nbt", "minedmap-resource", "minedmap-types", + "notify", "num-integer", "num_cpus", "phf", @@ -656,6 +736,43 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "notify" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" +dependencies = [ + "bitflags 2.8.0", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.59.0", +] + +[[package]] +name = "notify-types" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -930,7 +1047,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -939,6 +1056,15 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1052,7 +1178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1171,6 +1297,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" @@ -1187,12 +1329,30 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index 998de6c..d213a56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ enum-map = "2.7.3" fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" +humantime = "2.1.0" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.13.0" @@ -51,6 +52,7 @@ minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", opt minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } minedmap-types = { version = "0.1.4", path = "crates/types" } +notify = "8.0.0" num-integer = "0.1.45" num_cpus = "1.16.0" phf = { version = "0.11.2", features = ["macros"] } diff --git a/src/core/common.rs b/src/core/common.rs index d311773..a81dbf2 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -135,6 +135,8 @@ pub enum TileKind { pub struct Config { /// Number of threads for parallel processing pub num_threads: usize, + /// Number of threads for initial parallel processing + pub num_threads_initial: usize, /// Path of input region directory pub region_dir: PathBuf, /// Path of input `level.dat` file @@ -169,6 +171,7 @@ impl Config { Some(threads) => threads, None => 1, }; + let num_threads_initial = args.jobs_initial.unwrap_or(num_threads); let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); @@ -189,6 +192,7 @@ impl Config { Ok(Config { num_threads, + num_threads_initial, region_dir, level_dat_path, level_dat_old_path, diff --git a/src/core/mod.rs b/src/core/mod.rs index 5832379..202d017 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -10,7 +10,12 @@ mod tile_merger; mod tile_mipmapper; mod tile_renderer; -use std::path::PathBuf; +use std::{ + path::PathBuf, + sync::mpsc::{self, Receiver}, + thread, + time::Duration, +}; use anyhow::{Context, Result}; use clap::Parser; @@ -18,9 +23,13 @@ use git_version::git_version; use common::{Config, ImageFormat}; use metadata_writer::MetadataWriter; +use notify::{RecommendedWatcher, RecursiveMode, Watcher as _}; +use rayon::ThreadPool; use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; +use tokio::runtime::Runtime; +use tracing::{info, warn}; use self::entity_collector::EntityCollector; @@ -44,9 +53,26 @@ pub struct Args { /// use one thread per logical CPU core. #[arg(short, long)] pub jobs: Option, + /// Number of parallel threads to use for initial processing + /// + /// Passing this option only makes sense with --watch. The first run after + /// starting MinedMap will use as many parallel jobs as configured using + /// --job-initial, while subsequent regenerations of tiles will use the + /// the number configured using --jobs. + /// + /// If not given, the value from the --jobs option is used. + #[arg(long)] + pub jobs_initial: Option, /// Enable verbose messages #[arg(short, long)] pub verbose: bool, + /// Watch for file changes and regenerate tiles automatically instead of + /// exiting after generation + #[arg(long)] + pub watch: bool, + /// Minimum delay between map generation cycles in watch mode + #[arg(long, value_parser = humantime::parse_duration, default_value = "30s")] + pub watch_delay: Duration, /// Format of generated map tiles #[arg(long, value_enum, default_value_t)] pub image_format: ImageFormat, @@ -74,14 +100,73 @@ pub struct Args { pub output_dir: PathBuf, } -/// Configures the Rayon thread pool for parallel processing -fn setup_threads(num_threads: usize) -> Result<()> { +/// Configures a Rayon thread pool for parallel processing +fn setup_threads(num_threads: usize) -> Result { rayon::ThreadPoolBuilder::new() .num_threads(num_threads) - .build_global() + .build() .context("Failed to configure thread pool") } +/// Runs all MinedMap generation steps, updating all tiles as needed +fn generate(config: &Config, rt: &Runtime) -> Result<()> { + let regions = RegionProcessor::new(config).run()?; + TileRenderer::new(config, rt, ®ions).run()?; + let tiles = TileMipmapper::new(config, ®ions).run()?; + EntityCollector::new(config, ®ions).run()?; + MetadataWriter::new(config, &tiles).run() +} + +/// Creates a file watcher for the +fn create_watcher(args: &Args) -> Result<(RecommendedWatcher, Receiver<()>)> { + let (tx, rx) = mpsc::sync_channel::<()>(1); + let mut watcher = notify::recommended_watcher(move |res| { + // Ignore errors - we already have a watch trigger queued if try_send() fails + let event: notify::Event = match res { + Ok(event) => event, + Err(err) => { + warn!("Watch error: {err}"); + return; + } + }; + let notify::EventKind::Modify(modify_kind) = event.kind else { + return; + }; + if !matches!( + modify_kind, + notify::event::ModifyKind::Data(_) + | notify::event::ModifyKind::Name(notify::event::RenameMode::To) + ) { + return; + } + if !event + .paths + .iter() + .any(|path| path.ends_with("level.dat") || path.extension() == Some("mcu".as_ref())) + { + return; + } + let _ = tx.try_send(()); + })?; + watcher.watch(&args.input_dir, RecursiveMode::Recursive)?; + Ok((watcher, rx)) +} + +/// Watches the data directory for changes, returning when a change has happened +fn wait_watcher(args: &Args, watch_channel: &Receiver<()>) -> Result<()> { + info!("Watching for changes..."); + let () = watch_channel + .recv() + .context("Failed to read watch event channel")?; + info!("Change detected."); + + thread::sleep(args.watch_delay); + + let _ = watch_channel.try_recv(); + + Ok(()) +} + /// MinedMap CLI main function pub fn cli() -> Result<()> { let args = Args::parse(); @@ -96,17 +181,26 @@ pub fn cli() -> Result<()> { .with_target(false) .init(); - setup_threads(config.num_threads)?; + let mut pool = setup_threads(config.num_threads_initial)?; let rt = tokio::runtime::Builder::new_current_thread() .build() .unwrap(); - let regions = RegionProcessor::new(&config).run()?; - TileRenderer::new(&config, &rt, ®ions).run()?; - let tiles = TileMipmapper::new(&config, ®ions).run()?; - EntityCollector::new(&config, ®ions).run()?; - MetadataWriter::new(&config, &tiles).run()?; + let watch = args.watch.then(|| create_watcher(&args)).transpose()?; - Ok(()) + pool.install(|| generate(&config, &rt))?; + + let Some((_watcher, watch_channel)) = watch else { + // watch mode disabled + return Ok(()); + }; + + if config.num_threads != config.num_threads_initial { + pool = setup_threads(config.num_threads)?; + } + pool.install(move || loop { + wait_watcher(&args, &watch_channel)?; + generate(&config, &rt)?; + }) } From d02ca9aea230b9ad387b21e7d911811ee67b6ab2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Feb 2025 17:28:47 +0100 Subject: [PATCH 106/152] ci: update OS --- .github/workflows/MinedMap.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index cf75b68..502e663 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -7,7 +7,7 @@ env: jobs: viewer: - runs-on: 'ubuntu-20.04' + runs-on: 'ubuntu-latest' steps: - name: 'Checkout' @@ -101,7 +101,7 @@ jobs: - os: 'windows-2019' target: 'i686-pc-windows-msvc' ext: '.exe' - - os: 'ubuntu-20.04' + - os: 'ubuntu-22.04' target: 'x86_64-unknown-linux-gnu' steps: From cb0aa235db5055fda339d3a7f0d80a60b41d3599 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Feb 2025 17:18:14 +0100 Subject: [PATCH 107/152] docker: move viewer Dockerfile to viewer subdirectory --- .github/workflows/MinedMap.yml | 1 + viewer/.dockerignore | 1 + Dockerfile.viewer => viewer/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 viewer/.dockerignore rename Dockerfile.viewer => viewer/Dockerfile (73%) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 502e663..198c472 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -25,6 +25,7 @@ jobs: pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-viewer' mkdir -p "$pkgdir" cp -r viewer/* "$pkgdir"/ + rm "$pkgdir"/Dockerfile - name: 'Archive' uses: 'actions/upload-artifact@v4' diff --git a/viewer/.dockerignore b/viewer/.dockerignore new file mode 100644 index 0000000..3af0ccb --- /dev/null +++ b/viewer/.dockerignore @@ -0,0 +1 @@ +/data diff --git a/Dockerfile.viewer b/viewer/Dockerfile similarity index 73% rename from Dockerfile.viewer rename to viewer/Dockerfile index 82d50bb..794bcf5 100644 --- a/Dockerfile.viewer +++ b/viewer/Dockerfile @@ -1,3 +1,3 @@ FROM docker.io/library/nginx:alpine -COPY viewer /usr/share/nginx/html +COPY . /usr/share/nginx/html # datadir should be mounted to: /usr/share/nginx/html/data From 3b5ce8287368881728b6af2a81568fdd90189f64 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Feb 2025 16:49:42 +0100 Subject: [PATCH 108/152] docker: include Alpine base tools, tini Including tini fixes forwarding signals to MinedMap, allowing to interrupt it using Ctrl-C. The base tools may be used to add a wrapper script to configure MinedMap with environment variables. As the Alpine base is included now, we can switch from the rust:alpine image to alpine:latest, resulting in MinedMap to be linked dynamically. --- .dockerignore | 4 ++++ Dockerfile | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cef6a14 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +* +!/Cargo.* +!/src +!/crates diff --git a/Dockerfile b/Dockerfile index fa3627c..04ce466 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ -FROM docker.io/library/rust:alpine AS BUILDER +FROM docker.io/library/alpine:latest AS BUILDER WORKDIR /build -RUN apk update && apk add cmake build-base +RUN apk add --no-cache build-base cmake cargo -COPY src /build/src -COPY crates /build/crates -COPY Cargo.toml Cargo.lock /build +COPY . . RUN cargo build -r +RUN strip target/release/minedmap -FROM scratch AS RUNNER +FROM docker.io/library/alpine:latest -COPY --from=BUILDER /build/target/release/minedmap /minedmap -ENTRYPOINT [ "/minedmap" ] +RUN apk add --no-cache libgcc tini + +COPY --from=BUILDER /build/target/release/minedmap /bin/minedmap +ENTRYPOINT [ "/sbin/tini", "--", "/bin/minedmap" ] From 850b1a668b49341e75ae17c7389a5e634383cdeb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 21 Feb 2025 19:06:05 +0100 Subject: [PATCH 109/152] docker: use lowercase stage name --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 04ce466..e052309 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/alpine:latest AS BUILDER +FROM docker.io/library/alpine:latest AS builder WORKDIR /build RUN apk add --no-cache build-base cmake cargo @@ -11,5 +11,5 @@ FROM docker.io/library/alpine:latest RUN apk add --no-cache libgcc tini -COPY --from=BUILDER /build/target/release/minedmap /bin/minedmap +COPY --from=builder /build/target/release/minedmap /bin/minedmap ENTRYPOINT [ "/sbin/tini", "--", "/bin/minedmap" ] From dba3dd551ecd504d81248db0855a510d479ab23d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 21 Feb 2025 10:51:05 +0100 Subject: [PATCH 110/152] ci: build Docker images, publish to GHCR --- .github/workflows/MinedMap.yml | 86 +++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 198c472..2aef1ec 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -1,5 +1,14 @@ name: 'MinedMap' -on: ['push', 'pull_request', 'workflow_dispatch'] +on: + push: + branches: + - 'main' + tags: + - 'v*' + pull_request: + branches: + - 'main' + workflow_dispatch: {} env: RUSTFLAGS: -Dwarnings @@ -139,3 +148,78 @@ jobs: with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' path: 'target/pkg' + + build-container: + runs-on: ubuntu-latest + needs: + - test + steps: + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/neocturne/minedmap/minedmap + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=branch,suffix=-{{sha}} + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/setup-buildx-action@v3 + + - name: Build + uses: docker/build-push-action@v6 + with: + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + viewer-container: + runs-on: ubuntu-latest + needs: + - test + steps: + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/neocturne/minedmap/viewer + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=branch,suffix=-{{sha}} + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/setup-buildx-action@v3 + + - name: Build + uses: docker/build-push-action@v6 + with: + context: "{{defaultContext}}:viewer" + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 7bc15f97de13b08fc0372cddd281820bc0488b2b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 22 Feb 2025 03:13:43 +0100 Subject: [PATCH 111/152] docker: viewer: use nginx:alpine-slim as base --- viewer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/Dockerfile b/viewer/Dockerfile index 794bcf5..524fd4c 100644 --- a/viewer/Dockerfile +++ b/viewer/Dockerfile @@ -1,3 +1,3 @@ -FROM docker.io/library/nginx:alpine +FROM docker.io/library/nginx:alpine-slim COPY . /usr/share/nginx/html # datadir should be mounted to: /usr/share/nginx/html/data From 282f62fc30352fa1ea801c2ae7652e538a922eb4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 22 Feb 2025 04:02:10 +0100 Subject: [PATCH 112/152] docker: run minedmap as unpriviledged user --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index e052309..bb0e0ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,12 @@ RUN strip target/release/minedmap FROM docker.io/library/alpine:latest +RUN addgroup -g 1000 -S minedmap \ + && adduser -S -D -H -u 1000 -h /output -s /sbin/nologin -G minedmap -g minedmap minedmap + RUN apk add --no-cache libgcc tini COPY --from=builder /build/target/release/minedmap /bin/minedmap ENTRYPOINT [ "/sbin/tini", "--", "/bin/minedmap" ] + +USER minedmap:minedmap From 8cb1eee60b82b0bfe00f3260ece281b269cd04fb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 22 Feb 2025 11:06:46 +0100 Subject: [PATCH 113/152] docker, ci: fix --version output When building the docker image manually, MINEDMAP_VERSION needs to be set explicitly to get a proper version string. --- .github/workflows/MinedMap.yml | 12 ++++++++++++ Dockerfile | 2 ++ src/core/mod.rs | 18 ++++++++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 2aef1ec..24895c9 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -154,6 +154,16 @@ jobs: needs: - test steps: + - name: 'Checkout' + uses: 'actions/checkout@v4' + + - name: 'Get version' + id: 'tag' + run: | + set -o pipefail + git fetch --prune --unshallow --tags -f + echo "tag=$(git describe --abbrev=7 --match='v*' | sed 's/^v//')" >> $GITHUB_OUTPUT + - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -182,6 +192,8 @@ jobs: - name: Build uses: docker/build-push-action@v6 with: + build-args: | + MINEDMAP_VERSION=${{ steps.tag.outputs.tag }} push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index bb0e0ad..49965db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM docker.io/library/alpine:latest AS builder +ARG MINEDMAP_VERSION + WORKDIR /build RUN apk add --no-cache build-base cmake cargo diff --git a/src/core/mod.rs b/src/core/mod.rs index 202d017..a16f620 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -33,17 +33,23 @@ use tracing::{info, warn}; use self::entity_collector::EntityCollector; -/// MinedMap version number -const VERSION: &str = git_version!( - args = ["--abbrev=7", "--match=v*", "--dirty=-modified"], - cargo_prefix = "v", -); +/// Returns the MinedMap version number +fn version() -> &'static str { + option_env!("MINEDMAP_VERSION").unwrap_or( + git_version!( + args = ["--abbrev=7", "--match=v*", "--dirty=-modified"], + cargo_prefix = "v", + ) + .strip_prefix("v") + .unwrap(), + ) +} /// Command line arguments for minedmap CLI #[derive(Debug, Parser)] #[command( about, - version = VERSION.strip_prefix("v").unwrap(), + version = version(), max_term_width = 100, )] pub struct Args { From 90f2c5fdd05286037512380950a9fe076fe26600 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 22 Feb 2025 04:03:08 +0100 Subject: [PATCH 114/152] docker: add example docker-compose.yml --- docker-compose.yml | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5954ba7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,51 @@ +# This is an example docker-compose configuration providing a Minecraft server, +# map generator and webserver. Visit http://localhost:8080 to view the map. +# +# See https://docker-minecraft-server.readthedocs.io/ for more information on +# the itzg/minecraft-server image and its configuration. + +services: + mc: + image: docker.io/itzg/minecraft-server + environment: + EULA: 'true' + ports: + - '25565:25565' + volumes: + - data:/data + stdin_open: true + tty: true + restart: unless-stopped + + minedmap: + image: ghcr.io/neocturne/minedmap/minedmap + command: + - '--jobs-initial=2' + - '--image-format=webp' + - '--sign-filter=\[Map\]' + - '--sign-transform=s/\[Map\]//' + - '--watch' + - '/input/world' + - '/output' + volumes: + - data:/input + - output:/output + - processed:/output/processed + network_mode: 'none' + depends_on: + mc: + condition: service_healthy + restart: unless-stopped + + viewer: + image: ghcr.io/neocturne/minedmap/viewer + ports: + - '8080:80' + volumes: + - output:/usr/share/nginx/html/data + restart: unless-stopped + +volumes: + data: {} + processed: {} + output: {} From 24c266fc78db01115435c118c874d55a5a9f2d28 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 22 Feb 2025 11:27:40 +0100 Subject: [PATCH 115/152] docker: set ARG after apk add Allow reusing apk add layer when MINEDMAP_VERSION has changed. Signed-off-by: Matthias Schiffer --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 49965db..389fb08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ FROM docker.io/library/alpine:latest AS builder -ARG MINEDMAP_VERSION - WORKDIR /build RUN apk add --no-cache build-base cmake cargo +ARG MINEDMAP_VERSION + COPY . . RUN cargo build -r RUN strip target/release/minedmap From 5ee8e493d4b85afa8f8090716bf04207e8425f3b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 25 Feb 2025 18:23:54 +0100 Subject: [PATCH 116/152] docker-compose.yml: mount volumes read-only where appropriate --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 5954ba7..c725ae2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: - '/input/world' - '/output' volumes: - - data:/input + - data:/input:ro - output:/output - processed:/output/processed network_mode: 'none' @@ -42,7 +42,7 @@ services: ports: - '8080:80' volumes: - - output:/usr/share/nginx/html/data + - output:/usr/share/nginx/html/data:ro restart: unless-stopped volumes: From 40bc6cd2a9aaa5137561604c025edb5677d81b14 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 28 Feb 2025 11:54:20 +0100 Subject: [PATCH 117/152] Update dependencies --- Cargo.lock | 80 +++++++++++++++++++------------------- crates/resource/Cargo.toml | 2 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 039e940..c8cbbe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "autocfg" @@ -150,9 +150,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.13" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -173,9 +173,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.29" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", @@ -183,9 +183,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.29" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", @@ -263,9 +263,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "either" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" [[package]] name = "enum-map" @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "libz-ng-sys", @@ -448,9 +448,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.29.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" +checksum = "17fcdf9683c406c2fc4d124afd29c0d595e22210d633cbdb8695ba9935ab1dc6" [[package]] name = "hashbrown" @@ -593,9 +593,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libredox" @@ -636,9 +636,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "lru" @@ -728,9 +728,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", "simd-adler32", @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ "bitflags 2.8.0", ] @@ -1073,9 +1073,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] @@ -1091,9 +1091,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", @@ -1102,9 +1102,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", @@ -1150,9 +1150,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "strsim" @@ -1281,9 +1281,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "utf8parse" @@ -1428,27 +1428,27 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.14+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" dependencies = [ "cc", "pkg-config", diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 4e0d512..07b6d1f 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -9,5 +9,5 @@ repository.workspace = true [dependencies] enumflags2 = { version = "0.7.7", features = ["serde"] } -glam = "0.29.2" +glam = "0.30.0" serde = { version = "1.0.183", features = ["derive"] } From f8c8ca78bad8e0c66b1429666442c958be1a33bf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 28 Feb 2025 12:12:58 +0100 Subject: [PATCH 118/152] Switch from zlib-ng to zlib-rs zlib-rs provides the same performance as zlib-ng with minedmap, while reducing the amount of C code and avoiding the external build dependency on CMake. --- CHANGELOG.md | 4 ++++ Cargo.lock | 27 ++++++++++++--------------- Cargo.toml | 4 ++-- Dockerfile | 2 +- README.md | 5 ----- crates/nbt/Cargo.toml | 6 ++---- 6 files changed, 21 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8fd052..1b84b15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,10 @@ - Unknown biome types (from not yet supported or modded versions of Minecraft) will now use plains biome colors as a fallback instead of resulting in water, grass and foliage blocks to be rendered as transparent pixels +- Switched from zlib-ng to zlib-rs + + This should have no noticable effect on the usage of MinedMap, but avoids + an external build dependency on CMake. ## [2.4.0] - 2025-01-11 diff --git a/Cargo.lock b/Cargo.lock index c8cbbe6..7bd83ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,15 +212,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" -[[package]] -name = "cmake" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" -dependencies = [ - "cc", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -364,7 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", - "libz-ng-sys", + "libz-rs-sys", "miniz_oxide", ] @@ -609,13 +600,12 @@ dependencies = [ ] [[package]] -name = "libz-ng-sys" -version = "1.1.21" +name = "libz-rs-sys" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cee1488e961a80d172564fd6fcda11d8a4ac6672c06fe008e9213fa60520c2b" +checksum = "902bc563b5d65ad9bba616b490842ef0651066a1a1dc3ce1087113ffcb873c8d" dependencies = [ - "cmake", - "libc", + "zlib-rs", ] [[package]] @@ -664,6 +654,7 @@ dependencies = [ "clap", "enum-map", "fastnbt", + "flate2", "futures-util", "git-version", "humantime", @@ -1426,6 +1417,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "zlib-rs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b20717f0917c908dc63de2e44e97f1e6b126ca58d0e391cee86d504eb8fbd05" + [[package]] name = "zstd" version = "0.13.3" diff --git a/Cargo.toml b/Cargo.toml index d213a56..812ad33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ bincode = "1.3.3" clap = { version = "4.1.4", features = ["derive", "wrap_help"] } enum-map = "2.7.3" fastnbt = "2.3.2" +flate2 = { version = "1.1.0", features = ["zlib-rs"] } futures-util = "0.3.28" git-version = "0.3.5" humantime = "2.1.0" @@ -67,7 +68,6 @@ tracing-subscriber = "0.3.17" zstd = "0.13.0" [features] -default = ["jemalloc-auto", "zlib-ng"] +default = ["jemalloc-auto"] jemalloc-auto = ["dep:minedmap-default-alloc"] jemalloc = ["jemalloc-auto", "minedmap-default-alloc/jemalloc"] -zlib-ng = ["minedmap-nbt/zlib-ng"] diff --git a/Dockerfile b/Dockerfile index 389fb08..818971d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM docker.io/library/alpine:latest AS builder WORKDIR /build -RUN apk add --no-cache build-base cmake cargo +RUN apk add --no-cache build-base cargo ARG MINEDMAP_VERSION diff --git a/README.md b/README.md index 7d60f78..952163f 100644 --- a/README.md +++ b/README.md @@ -117,11 +117,6 @@ or newer). The following command can be used to build the current development ve cargo install --git 'https://github.com/neocturne/MinedMap.git' ``` -In addition, CMake is needed to build the zlib-ng library. If you do not have -CMake installed, you can disable the zlib-ng feature by passing `--no-default-features` -to cargo. A pure-Rust zlib implementation will be used, which is more portable, -but slower than zlib-ng. - If you are looking for the older C++ implementation of the MinedMap tile renderer, see the [v1.19.1](https://github.com/neocturne/MinedMap/tree/v1.19.1) tag. diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index 9f815da..01bbd78 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -11,12 +11,10 @@ repository.workspace = true anyhow = "1.0.75" bytemuck = "1.13.1" fastnbt = "2.4.4" -flate2 = "1.0.27" +flate2 = "1.1.0" minedmap-types = { version = "0.1.4", path = "../types" } serde = "1.0.183" -[features] -zlib-ng = ["flate2/zlib-ng"] - [dev-dependencies] clap = { version = "4.3.23", features = ["derive"] } +flate2 = { version = "1.1.0", features = ["zlib-rs"] } From 7686996fd3b538d3b5409fcb3c251b178ed693df Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 28 Feb 2025 16:16:29 +0100 Subject: [PATCH 119/152] resource: make seagrass opaque See changelog for rationale. --- CHANGELOG.md | 7 +++++++ crates/resource/src/block_types.rs | 4 ++-- resource/blocks.json | 2 +- src/core/common.rs | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b84b15..14b7e35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,13 @@ This should have no noticable effect on the usage of MinedMap, but avoids an external build dependency on CMake. +- Small (1-block) seagrass is now visible on the map + + 1-block seagrass in 1-block deep water would previously result in the ground + to be shown instead of water, as MinedMap currently doesn't handle the + "waterlogged" block status. As 1-block seagrass is relatively big compared to + other "small" plants, just considering it opaque seems like a good enough + solution that avoids having to implement advanced block status flags. ## [2.4.0] - 2025-01-11 diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 53abd54..da556b8 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -8692,8 +8692,8 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ "seagrass", ConstBlockType { block_color: BlockColor { - flags: make_bitflags!(BlockFlag::{}), - color: Color([0, 0, 0]), + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([50, 126, 8]), }, sign_material: None, }, diff --git a/resource/blocks.json b/resource/blocks.json index a88aa34..a409abb 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -1781,7 +1781,7 @@ "sculk_vein": {}, "sea_lantern": {}, "sea_pickle": {}, - "seagrass": null, + "seagrass": {}, "short_grass": null, "shroomlight": {}, "shulker_box": {}, diff --git a/src/core/common.rs b/src/core/common.rs index a81dbf2..8230a79 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -25,7 +25,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(4); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(5); /// MinedMap map tile data version number /// @@ -37,7 +37,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(4); /// MinedMap mipmap data version number /// From fbdd5ed457f2e5ca12bc7a7d6f6992f47494e062 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 21:11:59 +0100 Subject: [PATCH 120/152] Dockerfile: switch back to docker.io/library/rust:alpine image bincode 2 required Rust 1.85, so our options are to switch to Alpine edge or to use the rust image. While using the rust image results in a statically linked binary, this does not actually increase the size of the image, as we were already using jemalloc, so almost nothing of libc is actually used. --- Dockerfile | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 818971d..0f0eecd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM docker.io/library/alpine:latest AS builder +FROM docker.io/library/rust:alpine AS builder WORKDIR /build -RUN apk add --no-cache build-base cargo +RUN apk add --no-cache build-base tini-static ARG MINEDMAP_VERSION @@ -9,14 +9,9 @@ COPY . . RUN cargo build -r RUN strip target/release/minedmap -FROM docker.io/library/alpine:latest +FROM scratch -RUN addgroup -g 1000 -S minedmap \ - && adduser -S -D -H -u 1000 -h /output -s /sbin/nologin -G minedmap -g minedmap minedmap +COPY --from=builder /sbin/tini-static /build/target/release/minedmap /bin/ +ENTRYPOINT [ "/bin/tini-static", "--", "/bin/minedmap" ] -RUN apk add --no-cache libgcc tini - -COPY --from=builder /build/target/release/minedmap /bin/minedmap -ENTRYPOINT [ "/sbin/tini", "--", "/bin/minedmap" ] - -USER minedmap:minedmap +USER 1000:1000 From deb232ddf356efd80a4658b0b0f8c329e420b244 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 20:34:16 +0100 Subject: [PATCH 121/152] Update dependencies --- Cargo.lock | 118 ++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bd83ee..0142276 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "autocfg" @@ -126,15 +126,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bytemuck" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" [[package]] name = "byteorder" @@ -173,9 +173,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.31" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", "clap_derive", @@ -183,9 +183,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstream", "anstyle", @@ -196,9 +196,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -254,9 +254,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "either" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "enum-map" @@ -468,9 +468,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "image" @@ -497,9 +497,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", @@ -512,7 +512,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" @@ -584,9 +584,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libredox" @@ -594,7 +594,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -610,9 +610,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" [[package]] name = "lock_api" @@ -745,7 +745,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "filetime", "fsevent-sys", "inotify", @@ -813,9 +813,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "overload" @@ -902,9 +902,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "png" @@ -921,9 +921,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -936,9 +936,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -980,11 +980,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -1030,11 +1030,11 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.38.44" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", @@ -1043,9 +1043,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1064,27 +1064,27 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.15" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1093,9 +1093,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1153,9 +1153,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1164,9 +1164,9 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ "rustix", "windows-sys 0.59.0", @@ -1204,9 +1204,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "parking_lot", @@ -1272,9 +1272,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "utf8parse" From 404ad74235cc69935204ea50497a80f9acce6aad Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 12 Mar 2025 20:54:04 +0100 Subject: [PATCH 122/152] core: deserialize biome list into Vec Only use IndexSet for deduplication while processing the biome; when deserializing, no deduplication is required, so using a Vec is faster (besides IndexSet missing non-serde support for bincode 2). --- src/core/common.rs | 3 +-- src/core/region_processor.rs | 12 ++++++++++-- src/core/tile_renderer.rs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 8230a79..b25d7b8 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -8,7 +8,6 @@ use std::{ use anyhow::{Context, Result}; use clap::ValueEnum; -use indexmap::IndexSet; use regex::{Regex, RegexSet}; use serde::{Deserialize, Serialize}; @@ -102,7 +101,7 @@ pub struct ProcessedRegion { /// List of biomes used in the region /// /// Indexed by [ProcessedChunk] biome data - pub biome_list: IndexSet, + pub biome_list: Vec, /// Processed chunk data pub chunks: ChunkArray>>, } diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index e448f5e..1dc50fb 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,9 +1,11 @@ //! The [RegionProcessor] and related functions -use std::{ffi::OsStr, path::PathBuf, sync::mpsc, time::SystemTime}; +use std::{ffi::OsStr, mem, path::PathBuf, sync::mpsc, time::SystemTime}; use anyhow::{Context, Result}; use enum_map::{Enum, EnumMap}; +use indexmap::IndexSet; +use minedmap_resource::Biome; use rayon::prelude::*; use tracing::{debug, info, warn}; @@ -73,6 +75,8 @@ struct SingleRegionProcessor<'a> { lightmap_needed: bool, /// True if entity output file needs to be updated entities_needed: bool, + /// [IndexSet] of biomes used by the processed region + biome_list: IndexSet, /// Processed region intermediate data processed_region: ProcessedRegion, /// Lightmap intermediate data @@ -108,6 +112,7 @@ impl<'a> SingleRegionProcessor<'a> { let entities_needed = Some(input_timestamp) > entities_timestamp; let processed_region = ProcessedRegion::default(); + let biome_list = IndexSet::default(); let lightmap = image::GrayAlphaImage::new(N, N); let entities = ProcessedEntities::default(); @@ -127,6 +132,7 @@ impl<'a> SingleRegionProcessor<'a> { lightmap_needed, entities_needed, processed_region, + biome_list, lightmap, entities, image_format: processor.config.tile_image_format(), @@ -220,7 +226,7 @@ impl<'a> SingleRegionProcessor<'a> { biomes, block_light, depths, - }) = world::layer::top_layer(&mut self.processed_region.biome_list, &chunk) + }) = world::layer::top_layer(&mut self.biome_list, &chunk) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? { if self.output_needed { @@ -291,6 +297,8 @@ impl<'a> SingleRegionProcessor<'a> { } } + self.processed_region.biome_list = mem::take(&mut self.biome_list).into_iter().collect(); + self.save_region()?; self.save_lightmap()?; self.save_entities()?; diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 24af234..e47e20e 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -187,7 +187,7 @@ impl<'a> TileRenderer<'a> { for ((region_x, region_z, index), w) in weights.into_values() { let region = region_group.get(region_x, region_z)?; - let biome = region.biome_list.get_index(index.into())?; + let biome = region.biome_list.get(usize::from(index))?; total += w; color += w * block_color(block, Some(biome), depth.0 as f32); From 53a0f2460006b89413feb80858a03673f2746b68 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 12 Mar 2025 20:34:26 +0100 Subject: [PATCH 123/152] treewide: update to bincode 2 Consistently use bincode's Encode/Decode to avoid issues with incompatible serde features. Support for storing some temporary files as JSON is removed. The size of the "processed" directory is reduced by ~8% with the new default encoding of bincode 2. Performance is more or less unaffected. --- Cargo.lock | 31 ++++++++++++++++++++--- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- crates/resource/src/lib.rs | 49 +++++++++++++++++++++++++++++++----- crates/types/Cargo.toml | 2 +- crates/types/src/lib.rs | 6 ++--- src/core/common.rs | 14 ++++++----- src/core/entity_collector.rs | 25 +++++++++--------- src/core/metadata_writer.rs | 5 ++-- src/core/region_processor.rs | 2 -- src/core/tile_renderer.rs | 3 +-- src/io/storage.rs | 46 +++++++++++++-------------------- src/world/block_entity.rs | 11 ++++---- src/world/json_text.rs | 7 ++++-- src/world/layer.rs | 4 +-- src/world/sign.rs | 5 ++-- 16 files changed, 133 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0142276..5c5d477 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,11 +111,22 @@ dependencies = [ [[package]] name = "bincode" -version = "1.3.3" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" dependencies = [ + "bincode_derive", "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", ] [[package]] @@ -704,17 +715,17 @@ dependencies = [ name = "minedmap-resource" version = "0.6.0" dependencies = [ + "bincode", "enumflags2", "glam", - "serde", ] [[package]] name = "minedmap-types" version = "0.1.4" dependencies = [ + "bincode", "itertools", - "serde", ] [[package]] @@ -1276,6 +1287,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1288,6 +1305,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 812ad33..4109bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ pre-release-replacements = [ [dependencies] anyhow = "1.0.68" -bincode = "1.3.3" +bincode = "2.0.1" clap = { version = "4.1.4", features = ["derive", "wrap_help"] } enum-map = "2.7.3" fastnbt = "2.3.2" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 07b6d1f..c654f40 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -8,6 +8,6 @@ readme.workspace = true repository.workspace = true [dependencies] +bincode = "2.0.1" enumflags2 = { version = "0.7.7", features = ["serde"] } glam = "0.30.0" -serde = { version = "1.0.183", features = ["derive"] } diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index a633d06..01b460b 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -10,13 +10,13 @@ mod legacy_block_types; use std::collections::HashMap; +use bincode::{BorrowDecode, Decode, Encode}; use enumflags2::{bitflags, BitFlags}; -use serde::{Deserialize, Serialize}; /// Flags describing special properties of [BlockType]s #[bitflags] #[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum BlockFlag { /// The block type is opaque Opaque, @@ -38,14 +38,14 @@ pub enum BlockFlag { } /// An RGB color with u8 components -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] pub struct Color(pub [u8; 3]); /// An RGB color with f32 components pub type Colorf = glam::Vec3; /// A block type specification -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy)] pub struct BlockColor { /// Bit set of [BlockFlag]s describing special properties of the block type pub flags: BitFlags, @@ -61,6 +61,43 @@ impl BlockColor { } } +impl Encode for BlockColor { + fn encode( + &self, + encoder: &mut E, + ) -> Result<(), bincode::error::EncodeError> { + bincode::Encode::encode(&self.flags.bits(), encoder)?; + bincode::Encode::encode(&self.color, encoder)?; + Ok(()) + } +} + +impl Decode for BlockColor { + fn decode>( + decoder: &mut D, + ) -> Result { + Ok(BlockColor { + flags: BitFlags::from_bits(bincode::Decode::decode(decoder)?).or(Err( + bincode::error::DecodeError::Other("invalid block flags"), + ))?, + color: bincode::Decode::decode(decoder)?, + }) + } +} + +impl<'de, Context> BorrowDecode<'de, Context> for BlockColor { + fn borrow_decode>( + decoder: &mut D, + ) -> Result { + Ok(BlockColor { + flags: BitFlags::from_bits(bincode::BorrowDecode::borrow_decode(decoder)?).or(Err( + bincode::error::DecodeError::Other("invalid block flags"), + ))?, + color: bincode::BorrowDecode::borrow_decode(decoder)?, + }) + } +} + /// A block type specification (for use in constants) #[derive(Debug, Clone)] struct ConstBlockType { @@ -137,7 +174,7 @@ impl BlockTypes { pub use block_color::{block_color, needs_biome}; /// Grass color modifier used by a biome -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)] pub enum BiomeGrassColorModifier { /// Grass color modifier used by the dark forest biome DarkForest, @@ -149,7 +186,7 @@ pub enum BiomeGrassColorModifier { /// /// A Biome contains all information about a biome necessary to compute a block /// color given a block type and depth -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encode, Decode)] pub struct Biome { /// Temperature value /// diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index c5bd47e..2b83c39 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -8,5 +8,5 @@ readme.workspace = true repository.workspace = true [dependencies] +bincode = "2.0.1" itertools = "0.14.0" -serde = { version = "1.0.183", features = ["derive"] } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index b4f12c2..e770f6a 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -8,8 +8,8 @@ use std::{ ops::{Index, IndexMut}, }; +use bincode::{Decode, Encode}; use itertools::iproduct; -use serde::{Deserialize, Serialize}; /// Const generic AXIS arguments for coordinate types pub mod axis { @@ -110,7 +110,7 @@ impl LayerBlockCoords { /// Generic array for data stored per block of a chunk layer /// /// Includes various convenient iteration functions. -#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); impl Index for LayerBlockArray { @@ -196,7 +196,7 @@ impl Debug for ChunkCoords { /// Generic array for data stored per chunk of a region /// /// Includes various convenient iteration functions. -#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { diff --git a/src/core/common.rs b/src/core/common.rs index b25d7b8..06a3277 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -3,13 +3,15 @@ use std::{ collections::{BTreeMap, BTreeSet}, fmt::Debug, + hash::Hash, path::{Path, PathBuf}, }; use anyhow::{Context, Result}; +use bincode::{Decode, Encode}; use clap::ValueEnum; use regex::{Regex, RegexSet}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use crate::{ io::fs::FileMetaVersion, @@ -24,7 +26,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(5); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(6); /// MinedMap map tile data version number /// @@ -46,7 +48,7 @@ pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap processed entity data version number /// /// Increase when entity collection changes bacause of code changes. -pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(1); +pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); /// Coordinate pair of a generated tile /// @@ -85,7 +87,7 @@ impl TileCoordMap { } /// Data structure for storing chunk data between processing and rendering steps -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Encode, Decode)] pub struct ProcessedChunk { /// Block type data pub blocks: Box, @@ -96,7 +98,7 @@ pub struct ProcessedChunk { } /// Data structure for storing region data between processing and rendering steps -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default, Encode, Decode)] pub struct ProcessedRegion { /// List of biomes used in the region /// @@ -107,7 +109,7 @@ pub struct ProcessedRegion { } /// Data structure for storing entity data between processing and collection steps -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default, Encode, Decode)] pub struct ProcessedEntities { /// List of block entities pub block_entities: Vec, diff --git a/src/core/entity_collector.rs b/src/core/entity_collector.rs index 30b3a86..0d18090 100644 --- a/src/core/entity_collector.rs +++ b/src/core/entity_collector.rs @@ -78,23 +78,22 @@ impl<'a> EntityCollector<'a> { let mut output = ProcessedEntities::default(); for source_path in sources { - let mut source: ProcessedEntities = - match storage::read_file(source_path.as_ref(), storage::Format::Json) { - Ok(source) => source, - Err(err) => { - warn!( - "Failed to read entity data file {}: {:?}", - source_path.as_ref().display(), - err, - ); - continue; - } - }; + let mut source: ProcessedEntities = match storage::read_file(source_path.as_ref()) { + Ok(source) => source, + Err(err) => { + warn!( + "Failed to read entity data file {}: {:?}", + source_path.as_ref().display(), + err, + ); + continue; + } + }; output.block_entities.append(&mut source.block_entities); } - storage::write(file, &output, storage::Format::Json).context("Failed to write entity data") + storage::write(file, &output).context("Failed to write entity data") } /// Runs the mipmap generation diff --git a/src/core/metadata_writer.rs b/src/core/metadata_writer.rs index eb5f59f..40c5796 100644 --- a/src/core/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -179,9 +179,8 @@ impl<'a> MetadataWriter<'a> { /// Generates [Entities] data from collected entity lists fn entities(&self) -> Result { - let data: ProcessedEntities = - storage::read_file(&self.config.entities_path_final, storage::Format::Json) - .context("Failed to read entity data file")?; + let data: ProcessedEntities = storage::read_file(&self.config.entities_path_final) + .context("Failed to read entity data file")?; let ret = Entities { signs: data diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 1dc50fb..56f54ed 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -168,7 +168,6 @@ impl<'a> SingleRegionProcessor<'a> { storage::write_file( &self.output_path, &self.processed_region, - storage::Format::Bincode, REGION_FILE_META_VERSION, self.input_timestamp, ) @@ -207,7 +206,6 @@ impl<'a> SingleRegionProcessor<'a> { storage::write_file( &self.entities_path, &self.entities, - storage::Format::Json, ENTITIES_FILE_META_VERSION, self.input_timestamp, ) diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index e47e20e..e990a63 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -105,8 +105,7 @@ impl<'a> TileRenderer<'a> { region_loader .get_or_try_init(|| async { - storage::read_file(&processed_path, storage::Format::Bincode) - .context("Failed to load processed region data") + storage::read_file(&processed_path).context("Failed to load processed region data") }) .await .cloned() diff --git a/src/io/storage.rs b/src/io/storage.rs index 9296166..ae311de 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -10,28 +10,16 @@ use std::{ }; use anyhow::{Context, Result}; -use serde::{de::DeserializeOwned, Serialize}; +use bincode::{Decode, Encode}; use super::fs; -/// Storage format -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Format { - /// Encode as Bincode - /// - /// Bincode is more efficient than JSON, but cannot handle many of - /// serde's features like flatten, conditional skipping, ... - Bincode, - /// Encode as JSON - Json, -} +/// Bincode configuration +const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard(); /// Serializes data and writes it to a writer -pub fn write(writer: &mut W, value: &T, format: Format) -> Result<()> { - let data = match format { - Format::Bincode => bincode::serialize(value)?, - Format::Json => serde_json::to_vec(value)?, - }; +pub fn write(writer: &mut W, value: &T) -> Result<()> { + let data = bincode::encode_to_vec(value, BINCODE_CONFIG)?; let len = u32::try_from(data.len())?; let compressed = zstd::bulk::compress(&data, 1)?; drop(data); @@ -45,18 +33,21 @@ pub fn write(writer: &mut W, value: &T, format: Format) /// Serializes data and stores it in a file /// /// A timestamp is stored in an assiciated metadata file. -pub fn write_file( +pub fn write_file( path: &Path, value: &T, - format: Format, version: fs::FileMetaVersion, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp(path, version, timestamp, |file| write(file, value, format)) + fs::create_with_timestamp(path, version, timestamp, |file| write(file, value)) } /// Reads data from a reader and deserializes it -pub fn read(reader: &mut R, format: Format) -> Result { +pub fn read(reader: &mut R) -> Result +where + R: Read, + T: Decode<()>, +{ let mut len_buf = [0u8; 4]; reader.read_exact(&mut len_buf)?; let len = usize::try_from(u32::from_be_bytes(len_buf))?; @@ -66,18 +57,17 @@ pub fn read(reader: &mut R, format: Format) -> Res let data = zstd::bulk::decompress(&compressed, len)?; drop(compressed); - let value = match format { - Format::Bincode => bincode::deserialize(&data)?, - Format::Json => serde_json::from_slice(&data)?, - }; - Ok(value) + Ok(bincode::decode_from_slice(&data, BINCODE_CONFIG)?.0) } /// Reads data from a file and deserializes it -pub fn read_file(path: &Path, format: Format) -> Result { +pub fn read_file(path: &Path) -> Result +where + T: Decode<()>, +{ (|| -> Result { let mut file = File::open(path)?; - read(&mut file, format) + read(&mut file) })() .with_context(|| format!("Failed to read file {}", path.display())) } diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs index 182ad50..6ad58a1 100644 --- a/src/world/block_entity.rs +++ b/src/world/block_entity.rs @@ -1,7 +1,8 @@ //! Processing of block entity data +use bincode::{Decode, Encode}; use minedmap_resource::{BlockFlag, BlockType}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use super::{ de, @@ -9,7 +10,7 @@ use super::{ }; /// Kind of sign block -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, Serialize)] #[serde(rename_all = "snake_case")] pub enum SignKind { /// Standing sign @@ -23,7 +24,7 @@ pub enum SignKind { } /// Processed sign data -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, Serialize)] pub struct Sign { /// The kind of the sign pub kind: SignKind, @@ -54,7 +55,7 @@ impl Sign { } /// Data for different kinds of [BlockEntity] -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, Serialize)] #[serde(tag = "type", rename_all = "snake_case")] pub enum BlockEntityData { /// A sign block @@ -62,7 +63,7 @@ pub enum BlockEntityData { } /// A processed block entity -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, Serialize)] pub struct BlockEntity { /// Global X coordinate pub x: i32, diff --git a/src/world/json_text.rs b/src/world/json_text.rs index fa18527..6a2d8ba 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -2,6 +2,7 @@ use std::{collections::VecDeque, fmt::Display}; +use bincode::{Decode, Encode}; use minedmap_resource::Color; use serde::{Deserialize, Serialize}; @@ -12,7 +13,9 @@ use serde::{Deserialize, Serialize}; /// is handled by [DeserializedText]. /// /// Formatting that is not set in a node is inherited from the parent. -#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)] +#[derive( + Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Encode, Decode, +)] pub struct FormattedText { #[serde(default)] /// Text content @@ -84,7 +87,7 @@ impl From for FormattedTextTree { } /// List of [FormattedText] -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Encode, Decode)] pub struct FormattedTextList(pub Vec); impl FormattedTextList { diff --git a/src/world/layer.rs b/src/world/layer.rs index e59593c..deb4b48 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -3,8 +3,8 @@ use std::num::NonZeroU16; use anyhow::{Context, Result}; +use bincode::{Decode, Encode}; use indexmap::IndexSet; -use serde::{Deserialize, Serialize}; use super::chunk::{Chunk, SectionIterItem}; use crate::{ @@ -13,7 +13,7 @@ use crate::{ }; /// Height (Y coordinate) of a block -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)] pub struct BlockHeight(pub i32); impl BlockHeight { diff --git a/src/world/sign.rs b/src/world/sign.rs index eff319f..579f5b3 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -2,8 +2,9 @@ use std::fmt::Display; +use bincode::{Decode, Encode}; use minedmap_resource::Color; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use super::{ de, @@ -104,7 +105,7 @@ impl BlockEntitySignExt for de::BlockEntitySign { } } -#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)] /// Deserialized and linearized sign text pub struct SignText(pub Vec); From 708fb9645dc89f6e454f3564b81f8e9a265457d7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 20:27:51 +0100 Subject: [PATCH 124/152] core/region_processor: refactor Separate configuration and mutable state, also allowing to avoid a few mem::take(). --- src/core/region_processor.rs | 115 ++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 48 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 56f54ed..e638342 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,6 +1,6 @@ //! The [RegionProcessor] and related functions -use std::{ffi::OsStr, mem, path::PathBuf, sync::mpsc, time::SystemTime}; +use std::{ffi::OsStr, path::PathBuf, sync::mpsc, time::SystemTime}; use anyhow::{Context, Result}; use enum_map::{Enum, EnumMap}; @@ -45,6 +45,37 @@ enum RegionProcessorStatus { ErrorMissing, } +/// Data of a region being processed by a [SingleRegionProcessor] +#[derive(Debug)] +struct SingleRegionData { + /// [IndexSet] of biomes used by the processed region + biome_list: IndexSet, + /// Processed region chunk intermediate data + chunks: ChunkArray>>, + /// Lightmap intermediate data + lightmap: image::GrayAlphaImage, + /// Processed entity intermediate data + entities: ProcessedEntities, + /// True if any unknown block or biome types were encountered during processing + has_unknown: bool, +} + +impl Default for SingleRegionData { + fn default() -> Self { + /// Width/height of the region data + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let lightmap = image::GrayAlphaImage::new(N, N); + Self { + biome_list: Default::default(), + chunks: Default::default(), + lightmap, + entities: Default::default(), + has_unknown: false, + } + } +} + /// Handles processing for a single region struct SingleRegionProcessor<'a> { /// Registry of known block types @@ -75,26 +106,13 @@ struct SingleRegionProcessor<'a> { lightmap_needed: bool, /// True if entity output file needs to be updated entities_needed: bool, - /// [IndexSet] of biomes used by the processed region - biome_list: IndexSet, - /// Processed region intermediate data - processed_region: ProcessedRegion, - /// Lightmap intermediate data - lightmap: image::GrayAlphaImage, - /// Processed entity intermediate data - entities: ProcessedEntities, /// Format of generated map tiles image_format: image::ImageFormat, - /// True if any unknown block or biome types were encountered during processing - has_unknown: bool, } impl<'a> SingleRegionProcessor<'a> { /// Initializes a [SingleRegionProcessor] fn new(processor: &'a RegionProcessor<'a>, coords: TileCoords) -> Result { - /// Width/height of the region data - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - let input_path = processor.config.region_path(coords); let input_timestamp = fs::modified_timestamp(&input_path)?; @@ -111,11 +129,6 @@ impl<'a> SingleRegionProcessor<'a> { let lightmap_needed = Some(input_timestamp) > lightmap_timestamp; let entities_needed = Some(input_timestamp) > entities_timestamp; - let processed_region = ProcessedRegion::default(); - let biome_list = IndexSet::default(); - let lightmap = image::GrayAlphaImage::new(N, N); - let entities = ProcessedEntities::default(); - Ok(SingleRegionProcessor { block_types: &processor.block_types, biome_types: &processor.biome_types, @@ -131,12 +144,7 @@ impl<'a> SingleRegionProcessor<'a> { output_needed, lightmap_needed, entities_needed, - processed_region, - biome_list, - lightmap, - entities, image_format: processor.config.tile_image_format(), - has_unknown: false, }) } @@ -160,14 +168,14 @@ impl<'a> SingleRegionProcessor<'a> { /// Saves processed region data /// /// The timestamp is the time of the last modification of the input region data. - fn save_region(&self) -> Result<()> { + fn save_region(&self, processed_region: &ProcessedRegion) -> Result<()> { if !self.output_needed { return Ok(()); } storage::write_file( &self.output_path, - &self.processed_region, + processed_region, REGION_FILE_META_VERSION, self.input_timestamp, ) @@ -176,7 +184,7 @@ impl<'a> SingleRegionProcessor<'a> { /// Saves a lightmap tile /// /// The timestamp is the time of the last modification of the input region data. - fn save_lightmap(&self) -> Result<()> { + fn save_lightmap(&self, lightmap: &image::GrayAlphaImage) -> Result<()> { if !self.lightmap_needed { return Ok(()); } @@ -186,7 +194,7 @@ impl<'a> SingleRegionProcessor<'a> { LIGHTMAP_FILE_META_VERSION, self.input_timestamp, |file| { - self.lightmap + lightmap .write_to(file, self.image_format) .context("Failed to save image") }, @@ -196,27 +204,32 @@ impl<'a> SingleRegionProcessor<'a> { /// Saves processed entity data /// /// The timestamp is the time of the last modification of the input region data. - fn save_entities(&mut self) -> Result<()> { + fn save_entities(&self, entities: &mut ProcessedEntities) -> Result<()> { if !self.entities_needed { return Ok(()); } - self.entities.block_entities.sort_unstable(); + entities.block_entities.sort_unstable(); storage::write_file( &self.entities_path, - &self.entities, + entities, ENTITIES_FILE_META_VERSION, self.input_timestamp, ) } /// Processes a single chunk - fn process_chunk(&mut self, chunk_coords: ChunkCoords, data: world::de::Chunk) -> Result<()> { + fn process_chunk( + &self, + data: &mut SingleRegionData, + chunk_coords: ChunkCoords, + chunk_data: world::de::Chunk, + ) -> Result<()> { let (chunk, has_unknown) = - world::chunk::Chunk::new(&data, self.block_types, self.biome_types) + world::chunk::Chunk::new(&chunk_data, self.block_types, self.biome_types) .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; - self.has_unknown |= has_unknown; + data.has_unknown |= has_unknown; if self.output_needed || self.lightmap_needed { if let Some(layer::LayerData { @@ -224,11 +237,11 @@ impl<'a> SingleRegionProcessor<'a> { biomes, block_light, depths, - }) = world::layer::top_layer(&mut self.biome_list, &chunk) + }) = world::layer::top_layer(&mut data.biome_list, &chunk) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? { if self.output_needed { - self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + data.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { blocks, biomes, depths, @@ -237,7 +250,7 @@ impl<'a> SingleRegionProcessor<'a> { if self.lightmap_needed { let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + overlay_chunk(&mut data.lightmap, &chunk_lightmap, chunk_coords); } } } @@ -249,20 +262,21 @@ impl<'a> SingleRegionProcessor<'a> { chunk_coords, ) })?; - self.entities.block_entities.append(&mut block_entities); + data.entities.block_entities.append(&mut block_entities); } Ok(()) } /// Processes the chunks of the region - fn process_chunks(&mut self) -> Result<()> { - crate::nbt::region::from_file(&self.input_path)? - .foreach_chunk(|chunk_coords, data| self.process_chunk(chunk_coords, data)) + fn process_chunks(&self, data: &mut SingleRegionData) -> Result<()> { + crate::nbt::region::from_file(&self.input_path)?.foreach_chunk( + |chunk_coords, chunk_data| self.process_chunk(data, chunk_coords, chunk_data), + ) } /// Processes the region - fn run(mut self) -> Result { + fn run(&self) -> Result { if !self.output_needed && !self.lightmap_needed && !self.entities_needed { debug!( "Skipping unchanged region r.{}.{}.mca", @@ -276,7 +290,9 @@ impl<'a> SingleRegionProcessor<'a> { self.coords.x, self.coords.z ); - if let Err(err) = self.process_chunks() { + let mut data = SingleRegionData::default(); + + if let Err(err) = self.process_chunks(&mut data) { if self.output_timestamp.is_some() && self.lightmap_timestamp.is_some() && self.entities_timestamp.is_some() @@ -295,13 +311,16 @@ impl<'a> SingleRegionProcessor<'a> { } } - self.processed_region.biome_list = mem::take(&mut self.biome_list).into_iter().collect(); + let processed_region = ProcessedRegion { + biome_list: data.biome_list.into_iter().collect(), + chunks: data.chunks, + }; - self.save_region()?; - self.save_lightmap()?; - self.save_entities()?; + self.save_region(&processed_region)?; + self.save_lightmap(&data.lightmap)?; + self.save_entities(&mut data.entities)?; - Ok(if self.has_unknown { + Ok(if data.has_unknown { RegionProcessorStatus::OkWithUnknown } else { RegionProcessorStatus::Ok From 5c8568755441c8e91fc8bf2ea598a021a0bd5477 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 20:40:23 +0100 Subject: [PATCH 125/152] Clean up dependency features --- Cargo.lock | 2 -- Cargo.toml | 4 ++-- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c5d477..4f5bfa2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -296,7 +296,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" dependencies = [ "enumflags2_derive", - "serde", ] [[package]] @@ -514,7 +513,6 @@ checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", - "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4109bfd..da9f2ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ futures-util = "0.3.28" git-version = "0.3.5" humantime = "2.1.0" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } -indexmap = { version = "2.0.0", features = ["serde"] } +indexmap = "2.0.0" lru = "0.13.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } @@ -60,7 +60,7 @@ phf = { version = "0.11.2", features = ["macros"] } rayon = "1.7.0" regex = "1.10.2" rustc-hash = "2.0.0" -serde = { version = "1.0.152", features = ["rc", "derive"] } +serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.99" tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } tracing = "0.1.37" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index c654f40..9fc157c 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -9,5 +9,5 @@ repository.workspace = true [dependencies] bincode = "2.0.1" -enumflags2 = { version = "0.7.7", features = ["serde"] } +enumflags2 = "0.7.7" glam = "0.30.0" From 7bba5bae558780a30e0c3218fc41ff770230b4cc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 21:24:44 +0100 Subject: [PATCH 126/152] Update to Rust 2024 With bincode 2, we require rust 1.85 anyways, so we might as well upgrade, too. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index da9f2ca..0051203 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ members = ["crates/*"] [workspace.package] -edition = "2021" +edition = "2024" license = "MIT" readme = "README.md" repository = "https://github.com/neocturne/MinedMap" From 775fcb2d1b6adcd8aca3196ebdd1b2b0f16818cb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 21:44:10 +0100 Subject: [PATCH 127/152] treewide: cargo fmt with 1.85 --- crates/nbt/src/region.rs | 4 ++-- crates/resource/src/lib.rs | 2 +- crates/types/src/lib.rs | 8 ++++---- src/core/mod.rs | 8 +++++--- src/core/tile_renderer.rs | 2 +- src/world/chunk.rs | 4 ++-- src/world/json_text.rs | 2 +- src/world/section.rs | 8 ++------ 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/crates/nbt/src/region.rs b/crates/nbt/src/region.rs index 8a52b9d..1325919 100644 --- a/crates/nbt/src/region.rs +++ b/crates/nbt/src/region.rs @@ -2,11 +2,11 @@ use std::{ fs::File, - io::{prelude::*, SeekFrom}, + io::{SeekFrom, prelude::*}, path::Path, }; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use flate2::read::ZlibDecoder; use serde::de::DeserializeOwned; diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index 01b460b..86cfb0f 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -11,7 +11,7 @@ mod legacy_block_types; use std::collections::HashMap; use bincode::{BorrowDecode, Decode, Encode}; -use enumflags2::{bitflags, BitFlags}; +use enumflags2::{BitFlags, bitflags}; /// Flags describing special properties of [BlockType]s #[bitflags] diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index e770f6a..f2dc0e1 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -48,10 +48,10 @@ macro_rules! coord_type { /// Returns an iterator over all possible values of the type #[inline] pub fn iter() -> impl DoubleEndedIterator> - + ExactSizeIterator - + FusedIterator - + Clone - + Debug { + + ExactSizeIterator + + FusedIterator + + Clone + + Debug { (0..Self::MAX as u8).map($t) } } diff --git a/src/core/mod.rs b/src/core/mod.rs index a16f620..fce2cb5 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -205,8 +205,10 @@ pub fn cli() -> Result<()> { if config.num_threads != config.num_threads_initial { pool = setup_threads(config.num_threads)?; } - pool.install(move || loop { - wait_watcher(&args, &watch_channel)?; - generate(&config, &rt)?; + pool.install(move || { + loop { + wait_watcher(&args, &watch_channel)?; + generate(&config, &rt)?; + } }) } diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index e990a63..9d7e188 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -16,7 +16,7 @@ use tracing::{debug, info}; use super::{common::*, region_group::RegionGroup}; use crate::{ io::{fs, storage}, - resource::{block_color, needs_biome, Colorf}, + resource::{Colorf, block_color, needs_biome}, types::*, util::coord_offset, }; diff --git a/src/world/chunk.rs b/src/world/chunk.rs index daee023..c4744d0 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -4,11 +4,11 @@ //! over different data versions as much as possible. use std::{ - collections::{btree_map, BTreeMap}, + collections::{BTreeMap, btree_map}, iter::{self, FusedIterator}, }; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use super::{block_entity::BlockEntity, de, section::*}; use crate::{ diff --git a/src/world/json_text.rs b/src/world/json_text.rs index 6a2d8ba..7d3ff3a 100644 --- a/src/world/json_text.rs +++ b/src/world/json_text.rs @@ -185,9 +185,9 @@ mod json_color { use minedmap_resource::Color; use serde::{ + Deserializer, Serializer, de::{self, Visitor}, ser::Error as _, - Deserializer, Serializer, }; /// Named JSON text colors diff --git a/src/world/section.rs b/src/world/section.rs index 845ddae..dc5c9a6 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use num_integer::div_rem; use tracing::debug; @@ -400,10 +400,6 @@ impl<'a> BlockLight<'a> { let (offset, nibble) = div_rem(coords.offset(), 2); let byte = block_light[offset] as u8; - if nibble == 1 { - byte >> 4 - } else { - byte & 0xf - } + if nibble == 1 { byte >> 4 } else { byte & 0xf } } } From 5ee826a11b78905eeefdacfc78fced7592ec8962 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 13 Mar 2025 21:52:35 +0100 Subject: [PATCH 128/152] ci: set fixed Rust version 1.85 Avoid CI failure due to new warnings or fmt changes in new Rust version. --- .github/workflows/MinedMap.yml | 11 +++++------ Dockerfile | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 24895c9..16a3047 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -48,7 +48,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: stable + toolchain: '1.85' components: rustfmt - run: cargo fmt --all -- --check @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: stable + toolchain: '1.85' components: clippy - uses: swatinem/rust-cache@v2 - uses: actions-rs/clippy-check@v1 @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: stable + toolchain: '1.85' components: rust-docs - uses: swatinem/rust-cache@v2 - run: cargo doc --workspace --no-deps --document-private-items @@ -83,12 +83,11 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - rust: [stable] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ matrix.rust }} + toolchain: '1.85' - uses: swatinem/rust-cache@v2 - run: cargo test --workspace - run: cargo test --workspace --no-default-features @@ -128,7 +127,7 @@ jobs: - uses: dtolnay/rust-toolchain@master with: - toolchain: stable + toolchain: '1.85' targets: '${{ matrix.target }}' - uses: swatinem/rust-cache@v2 diff --git a/Dockerfile b/Dockerfile index 0f0eecd..41d4c6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/rust:alpine AS builder +FROM docker.io/library/rust:1.85-alpine AS builder WORKDIR /build RUN apk add --no-cache build-base tini-static From d6cd0fc53bd42209b204311eee0e334e80aaf970 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 12:19:39 +0100 Subject: [PATCH 129/152] ci: include target in cache key Avoid cache keys colliding between build jobs running on the same OS. --- .github/workflows/MinedMap.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 16a3047..40ea96a 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -131,6 +131,8 @@ jobs: targets: '${{ matrix.target }}' - uses: swatinem/rust-cache@v2 + with: + key: '${{ matrix.target }}' - name: 'Build' shell: 'bash' From e600a9dabb27857f729f97e89e7866b084fef72a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 16:24:22 +0100 Subject: [PATCH 130/152] CHANGELOG.md: mention Bincode update While the update is an internal change, it does affect the MSRV, so it should be mentioned in the changelog. --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14b7e35..089e28a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,11 @@ "waterlogged" block status. As 1-block seagrass is relatively big compared to other "small" plants, just considering it opaque seems like a good enough solution that avoids having to implement advanced block status flags. +- Use Bincode 2 for storage of intermediate data + + The update from Bincode 1 to 2 slightly reduces the size of the `processed` + directory used for intermediate data. At least Rust 1.85 is now required to + build MinedMap. ## [2.4.0] - 2025-01-11 From dca365f4e23f7427571bfe943437a65cd48fc864 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 16:29:23 +0100 Subject: [PATCH 131/152] CHANGELOG.md: mention new Docker images and docker-compose example --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 089e28a..4f5c5bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,11 @@ Note that some platforms like `msvc` are unsupported by jemalloc, and trying to enable the `jemalloc` feature on these platforms may break the MinedMap build or cause issues at runtime. +- Docker images can be downloaded from the GitHub Container registry + + Two images are provided, one for the tile renderer and one with the viewer + and a web server. A `docker-compose.yml` example can be found in the + repository as a starting point. ### Changed From 6a54f57c509c6455371b0594b32a353920270fa2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 20:02:13 +0100 Subject: [PATCH 132/152] minedmap-types 0.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/nbt/Cargo.toml | 2 +- crates/types/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f5bfa2..80766f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -720,7 +720,7 @@ dependencies = [ [[package]] name = "minedmap-types" -version = "0.1.4" +version = "0.2.0" dependencies = [ "bincode", "itertools", diff --git a/Cargo.toml b/Cargo.toml index 0051203..854a955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ lru = "0.13.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.6.0", path = "crates/resource" } -minedmap-types = { version = "0.1.4", path = "crates/types" } +minedmap-types = { version = "0.2.0", path = "crates/types" } notify = "8.0.0" num-integer = "0.1.45" num_cpus = "1.16.0" diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index 01bbd78..6a4938e 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -12,7 +12,7 @@ anyhow = "1.0.75" bytemuck = "1.13.1" fastnbt = "2.4.4" flate2 = "1.1.0" -minedmap-types = { version = "0.1.4", path = "../types" } +minedmap-types = { version = "0.2.0", path = "../types" } serde = "1.0.183" [dev-dependencies] diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 2b83c39..34caa1c 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-types" -version = "0.1.4" +version = "0.2.0" description = "Common types used by several MinedMap crates" edition.workspace = true license.workspace = true From 54ea2b2f2898a272be3ea4841d68081f9d1ff53d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 20:02:36 +0100 Subject: [PATCH 133/152] minedmap-resource 0.7.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80766f4..d5159bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -711,7 +711,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.6.0" +version = "0.7.0" dependencies = [ "bincode", "enumflags2", diff --git a/Cargo.toml b/Cargo.toml index 854a955..33256e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ indexmap = "2.0.0" lru = "0.13.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.6.0", path = "crates/resource" } +minedmap-resource = { version = "0.7.0", path = "crates/resource" } minedmap-types = { version = "0.2.0", path = "crates/types" } notify = "8.0.0" num-integer = "0.1.45" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 9fc157c..1257a90 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.6.0" +version = "0.7.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From 974a0f37df6dab8d0ca529a78bb6615e57ed05db Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 14 Mar 2025 20:02:49 +0100 Subject: [PATCH 134/152] minedmap-nbt 0.2.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/nbt/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5159bf..726fd48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,7 +698,7 @@ dependencies = [ [[package]] name = "minedmap-nbt" -version = "0.1.1" +version = "0.2.0" dependencies = [ "anyhow", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index 33256e6..9b87ed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ image = { version = "0.25.1", default-features = false, features = ["png", "webp indexmap = "2.0.0" lru = "0.13.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } -minedmap-nbt = { version = "0.1.1", path = "crates/nbt", default-features = false } +minedmap-nbt = { version = "0.2.0", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.7.0", path = "crates/resource" } minedmap-types = { version = "0.2.0", path = "crates/types" } notify = "8.0.0" diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index 6a4938e..07a5fd7 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-nbt" -version = "0.1.1" +version = "0.2.0" description = "MinedMap's handling of Minecraft NBT data and region files" edition.workspace = true license.workspace = true From 6e5b958912be6e8c3e64d94c8b30d565847ced7f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Mar 2025 12:17:07 +0100 Subject: [PATCH 135/152] default-alloc: fix wildcard dependency --- crates/default-alloc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/default-alloc/Cargo.toml b/crates/default-alloc/Cargo.toml index 40f9e7e..b03a871 100644 --- a/crates/default-alloc/Cargo.toml +++ b/crates/default-alloc/Cargo.toml @@ -11,7 +11,7 @@ repository.workspace = true tikv-jemallocator = { version = "0.6.0", optional = true } [target.'cfg(target_env = "musl")'.dependencies] -tikv-jemallocator = "*" +tikv-jemallocator = "0.6.0" [features] jemalloc = ["dep:tikv-jemallocator"] From 3008203080e2ae44f2eea35121d8ae790f219dc0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Mar 2025 12:24:29 +0100 Subject: [PATCH 136/152] minedmap 2.5.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f5c5bd..482d462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.5.0] - 2025-03-16 + ### Added - Added experimental watch mode @@ -186,7 +188,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.4.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.5.0...HEAD +[2.5.0]: https://github.com/neocturne/MinedMap/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/neocturne/MinedMap/compare/v2.3.1...v2.4.0 [2.3.1]: https://github.com/neocturne/MinedMap/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/neocturne/MinedMap/compare/v2.2.0...v2.3.0 diff --git a/Cargo.lock b/Cargo.lock index 726fd48..6b6d6ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -656,7 +656,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minedmap" -version = "2.4.0" +version = "2.5.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 9b87ed1..34e5619 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.4.0" +version = "2.5.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From 23b2f274be781fe20b24d778adb36595923be725 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Apr 2025 19:04:15 +0200 Subject: [PATCH 137/152] ci, docker: update to Rust 1.85.1 --- .github/workflows/MinedMap.yml | 10 +++++----- Dockerfile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 40ea96a..ece4e50 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -48,7 +48,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85' + toolchain: '1.85.1' components: rustfmt - run: cargo fmt --all -- --check @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85' + toolchain: '1.85.1' components: clippy - uses: swatinem/rust-cache@v2 - uses: actions-rs/clippy-check@v1 @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85' + toolchain: '1.85.1' components: rust-docs - uses: swatinem/rust-cache@v2 - run: cargo doc --workspace --no-deps --document-private-items @@ -87,7 +87,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85' + toolchain: '1.85.1' - uses: swatinem/rust-cache@v2 - run: cargo test --workspace - run: cargo test --workspace --no-default-features @@ -127,7 +127,7 @@ jobs: - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85' + toolchain: '1.85.1' targets: '${{ matrix.target }}' - uses: swatinem/rust-cache@v2 diff --git a/Dockerfile b/Dockerfile index 41d4c6c..ad36c79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/rust:1.85-alpine AS builder +FROM docker.io/library/rust:1.85.1-alpine AS builder WORKDIR /build RUN apk add --no-cache build-base tini-static From 442009eb0804891fdca520edbbbb61dabb12ef2e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Apr 2025 19:05:52 +0200 Subject: [PATCH 138/152] Update dependencies --- Cargo.lock | 105 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b6d6ff..d9f14f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -184,9 +184,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -360,9 +360,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "libz-rs-sys", @@ -371,9 +371,9 @@ dependencies = [ [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "fsevent-sys" @@ -421,6 +421,18 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + [[package]] name = "gimli" version = "0.31.1" @@ -449,9 +461,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.30.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17fcdf9683c406c2fc4d124afd29c0d595e22210d633cbdb8695ba9935ab1dc6" +checksum = "bf3aa70d918d2b234126ff4f850f628f172542bf0603ded26b8ee36e5e22d5f9" [[package]] name = "hashbrown" @@ -484,9 +496,9 @@ checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "image" -version = "0.25.5" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" dependencies = [ "bytemuck", "byteorder-lite", @@ -558,10 +570,11 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom", "libc", ] @@ -610,18 +623,18 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902bc563b5d65ad9bba616b490842ef0651066a1a1dc3ce1087113ffcb873c8d" +checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a" dependencies = [ "zlib-rs", ] [[package]] name = "linux-raw-sys" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "lock_api" @@ -635,9 +648,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" @@ -744,7 +757,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -822,9 +835,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "overload" @@ -952,6 +965,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1039,9 +1058,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", @@ -1325,6 +1344,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1439,10 +1467,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "zlib-rs" -version = "0.4.2" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b20717f0917c908dc63de2e44e97f1e6b126ca58d0e391cee86d504eb8fbd05" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "zlib-rs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8" [[package]] name = "zstd" @@ -1455,18 +1492,18 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "7.2.3" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.14+zstd.1.5.7" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", From ba6e4bae7f072c697e1d204955f72ed2a6bbb148 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Apr 2025 22:39:26 +0200 Subject: [PATCH 139/152] world: rename JSONText to TextValue New Minecraft version do not store text as JSON anymore. --- src/world/de.rs | 12 ++++++------ src/world/mod.rs | 2 +- src/world/sign.rs | 4 ++-- src/world/{json_text.rs => text_value.rs} | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 20 deletions(-) rename src/world/{json_text.rs => text_value.rs} (93%) diff --git a/src/world/de.rs b/src/world/de.rs index 7ab8ba7..0a4b4b6 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -2,7 +2,7 @@ use serde::Deserialize; -use super::json_text::JSONText; +use super::text_value::TextValue; /// Element of the `palette` list of 1.18+ [block states](BlockStatesV1_18) #[derive(Debug, Deserialize)] @@ -110,7 +110,7 @@ pub enum BiomesV0 { #[derive(Debug, Deserialize)] pub struct BlockEntitySignV1_20Text { /// Lines of sign text - pub messages: Vec, + pub messages: Vec, /// Default text color pub color: Option, } @@ -125,13 +125,13 @@ pub enum BlockEntitySign { #[serde(rename_all = "PascalCase")] V0 { /// Line 1 of the sign text - text1: JSONText, + text1: TextValue, /// Line 2 of the sign text - text2: JSONText, + text2: TextValue, /// Line 3 of the sign text - text3: JSONText, + text3: TextValue, /// Line 4 of the sign text - text4: JSONText, + text4: TextValue, /// Default text color color: Option, }, diff --git a/src/world/mod.rs b/src/world/mod.rs index 6426c92..8a2e9be 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -3,7 +3,7 @@ pub mod block_entity; pub mod chunk; pub mod de; -pub mod json_text; pub mod layer; pub mod section; pub mod sign; +pub mod text_value; diff --git a/src/world/sign.rs b/src/world/sign.rs index 579f5b3..c913b6f 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -8,7 +8,7 @@ use serde::Serialize; use super::{ de, - json_text::{FormattedText, FormattedTextList, JSONText}, + text_value::{FormattedText, FormattedTextList, TextValue}, }; /// Version-independent reference to (front or back) sign text @@ -18,7 +18,7 @@ pub struct RawSignText<'a> { /// /// A regular sign always has 4 lines of text. The back of pre-1.20 /// signs is represented as a [SignText] without any `messages`. - pub messages: Vec<&'a JSONText>, + pub messages: Vec<&'a TextValue>, /// Sign color /// /// Defaults to "black". diff --git a/src/world/json_text.rs b/src/world/text_value.rs similarity index 93% rename from src/world/json_text.rs rename to src/world/text_value.rs index 7d3ff3a..336b1b1 100644 --- a/src/world/json_text.rs +++ b/src/world/text_value.rs @@ -1,4 +1,4 @@ -//! Newtype and helper methods for handling Minecraft Raw JSON Text +//! Newtype and helper methods for handling Minecraft text values use std::{collections::VecDeque, fmt::Display}; @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; /// A span of formatted text /// -/// A [JSONText] consists of a tree of [FormattedText] nodes (canonically +/// A [TextValue] consists of a tree of [FormattedText] nodes (canonically /// represented as a [FormattedTextTree], but other kinds are possible with /// is handled by [DeserializedText]. /// @@ -21,7 +21,7 @@ pub struct FormattedText { /// Text content pub text: String, /// Text color - #[serde(skip_serializing_if = "Option::is_none", with = "json_color")] + #[serde(skip_serializing_if = "Option::is_none", with = "text_color")] pub color: Option, /// Bold formatting #[serde(skip_serializing_if = "Option::is_none")] @@ -107,9 +107,9 @@ impl Display for FormattedTextList { } } -/// Raw deserialized [JSONText] +/// Raw deserialized [TextValue] /// -/// A [JSONText] can contain various different JSON types. +/// A [TextValue] can contain various different types serialized as JSON or NBT. #[derive(Debug, Deserialize)] #[serde(untagged)] pub enum DeserializedText { @@ -169,18 +169,18 @@ impl Default for DeserializedText { } } -/// Minecraft Raw JSON Text +/// Minecraft raw text value #[derive(Debug, Deserialize)] -pub struct JSONText(pub String); +pub struct TextValue(pub String); -impl JSONText { - /// Deserializes a [JSONText] into a [DeserializedText] +impl TextValue { + /// Deserializes a [TextValue] into a [DeserializedText] pub fn deserialize(&self) -> DeserializedText { serde_json::from_str(&self.0).unwrap_or_default() } } -mod json_color { +mod text_color { //! Helpers for serializing and deserializing [FormattedText](super::FormattedText) colors use minedmap_resource::Color; @@ -190,7 +190,7 @@ mod json_color { ser::Error as _, }; - /// Named JSON text colors + /// Named text colors static COLORS: phf::Map<&'static str, Color> = phf::phf_map! { "black" => Color([0x00, 0x00, 0x00]), "dark_blue" => Color([0x00, 0x00, 0xAA]), From 5f84ec8ed2c4701c24032bac0ee45175f2904ddc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Apr 2025 22:43:02 +0200 Subject: [PATCH 140/152] world/text_value: add support for new NBT text serialization Starting with DataVersion 4290, text is stored as NBT instead of JSON. The structure remains the same. --- src/world/block_entity.rs | 19 ++++++++++++++----- src/world/chunk.rs | 9 ++++++++- src/world/sign.rs | 4 ++-- src/world/text_value.rs | 14 +++++++++++--- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/world/block_entity.rs b/src/world/block_entity.rs index 6ad58a1..589a53c 100644 --- a/src/world/block_entity.rs +++ b/src/world/block_entity.rs @@ -41,10 +41,15 @@ pub struct Sign { impl Sign { /// Processes a [de::BlockEntitySign] into a [Sign] - fn new(sign: &de::BlockEntitySign, kind: SignKind, material: Option) -> Sign { + fn new( + sign: &de::BlockEntitySign, + kind: SignKind, + material: Option, + data_version: u32, + ) -> Sign { let (front_text, back_text) = sign.text(); - let front_text = front_text.decode(); - let back_text = back_text.decode(); + let front_text = front_text.decode(data_version); + let back_text = back_text.decode(data_version); Sign { kind, material, @@ -78,7 +83,11 @@ pub struct BlockEntity { impl BlockEntity { /// Processes a [de::BlockEntity] into a [BlockEntity] - pub fn new(entity: &de::BlockEntity, block_type: Option<&BlockType>) -> Option { + pub fn new( + entity: &de::BlockEntity, + block_type: Option<&BlockType>, + data_version: u32, + ) -> Option { let wall_sign = block_type .map(|block_type| block_type.block_color.is(BlockFlag::WallSign)) .unwrap_or_default(); @@ -92,7 +101,7 @@ impl BlockEntity { let material = block_type .as_ref() .and_then(|block_type| block_type.sign_material.as_ref()); - let data = BlockEntityData::Sign(Sign::new(sign, kind, material.cloned())); + let data = BlockEntityData::Sign(Sign::new(sign, kind, material.cloned(), data_version)); Some(BlockEntity { x: entity.x, diff --git a/src/world/chunk.rs b/src/world/chunk.rs index c4744d0..311fca8 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -58,6 +58,8 @@ pub struct Chunk<'a> { inner: ChunkInner<'a>, /// Unprocessed block entities block_entities: &'a Vec, + /// Chunk data version + data_version: u32, } impl<'a> Chunk<'a> { @@ -87,6 +89,7 @@ impl<'a> Chunk<'a> { Chunk { inner, block_entities, + data_version, }, has_unknown, )) @@ -292,7 +295,11 @@ impl<'a> Chunk<'a> { .iter() .map(|block_entity| { let block_type = self.block_type_at_block_entity(block_entity)?; - Ok(BlockEntity::new(block_entity, block_type)) + Ok(BlockEntity::new( + block_entity, + block_type, + self.data_version, + )) }) .collect::>()?; Ok(entities.into_iter().flatten().collect()) diff --git a/src/world/sign.rs b/src/world/sign.rs index c913b6f..8e4e670 100644 --- a/src/world/sign.rs +++ b/src/world/sign.rs @@ -49,7 +49,7 @@ static DYE_COLORS: phf::Map<&'static str, Color> = phf::phf_map! { impl RawSignText<'_> { /// Decodes the [RawSignText] into a [SignText] - pub fn decode(&self) -> SignText { + pub fn decode(&self, data_version: u32) -> SignText { let color = self .color .map(|c| DYE_COLORS.get(c).copied().unwrap_or(DEFAULT_COLOR)); @@ -60,7 +60,7 @@ impl RawSignText<'_> { SignText( self.messages .iter() - .map(|message| message.deserialize().linearize(&parent)) + .map(|message| message.deserialize(data_version).linearize(&parent)) .collect(), ) } diff --git a/src/world/text_value.rs b/src/world/text_value.rs index 336b1b1..75defc4 100644 --- a/src/world/text_value.rs +++ b/src/world/text_value.rs @@ -171,12 +171,20 @@ impl Default for DeserializedText { /// Minecraft raw text value #[derive(Debug, Deserialize)] -pub struct TextValue(pub String); +pub struct TextValue(pub fastnbt::Value); impl TextValue { /// Deserializes a [TextValue] into a [DeserializedText] - pub fn deserialize(&self) -> DeserializedText { - serde_json::from_str(&self.0).unwrap_or_default() + pub fn deserialize(&self, data_version: u32) -> DeserializedText { + if data_version < 4290 { + if let fastnbt::Value::String(json) = &self.0 { + if let Ok(content) = serde_json::from_str(json) { + return content; + } + } + } + + fastnbt::from_value(&self.0).unwrap_or_default() } } From 42b302f493a0824efa912fb8c56cf16c19adc266 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Apr 2025 19:05:09 +0200 Subject: [PATCH 141/152] resource: add new Minecraft 1.21.5 block types --- CHANGELOG.md | 6 ++ crates/resource/src/block_types.rs | 90 ++++++++++++++++++++++++++++++ resource/blocks.json | 11 ++++ src/core/common.rs | 4 +- 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 482d462..f96ddca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] - ReleaseDate +### Added + +- Added support for Minecraft 1.21.5 + + Added new block types and handling for changed sign text storage format. + ## [2.5.0] - 2025-03-16 ### Added diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index da556b8..044a153 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -1488,6 +1488,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "bush", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), + color: Color([119, 120, 119]), + }, + sign_material: None, + }, + ), ( "cactus", ConstBlockType { @@ -1498,6 +1508,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "cactus_flower", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([209, 120, 135]), + }, + sign_material: None, + }, + ), ( "cake", ConstBlockType { @@ -3808,6 +3828,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "firefly_bush", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([87, 83, 43]), + }, + sign_material: None, + }, + ), ( "fletching_table", ConstBlockType { @@ -4878,6 +4908,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "leaf_litter", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "lectern", ConstBlockType { @@ -8698,6 +8738,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "short_dry_grass", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([187, 158, 108]), + }, + sign_material: None, + }, + ), ( "short_grass", ConstBlockType { @@ -9638,6 +9688,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "tall_dry_grass", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([196, 171, 122]), + }, + sign_material: None, + }, + ), ( "tall_grass", ConstBlockType { @@ -9678,6 +9738,26 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "test_block", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), + ( + "test_instance_block", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "tinted_glass", ConstBlockType { @@ -10828,6 +10908,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "wildflowers", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + sign_material: None, + }, + ), ( "wither_rose", ConstBlockType { diff --git a/resource/blocks.json b/resource/blocks.json index a409abb..caf6f8a 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -316,9 +316,13 @@ "bubble_coral_fan": null, "bubble_coral_wall_fan": null, "budding_amethyst": {}, + "bush": { + "grass": true + }, "cactus": { "texture": "cactus_top" }, + "cactus_flower": {}, "cake": { "texture": "cake_top" }, @@ -778,6 +782,7 @@ "fire_coral_block": {}, "fire_coral_fan": null, "fire_coral_wall_fan": null, + "firefly_bush": {}, "fletching_table": { "texture": "fletching_table_top" }, @@ -987,6 +992,7 @@ "lava_cauldron": { "texture": "cauldron_top" }, + "leaf_litter": null, "lectern": { "texture": "lectern_top" }, @@ -1782,6 +1788,7 @@ "sea_lantern": {}, "sea_pickle": {}, "seagrass": {}, + "short_dry_grass": {}, "short_grass": null, "shroomlight": {}, "shulker_box": {}, @@ -2013,6 +2020,7 @@ "sweet_berry_bush": { "texture": "sweet_berry_bush_stage3" }, + "tall_dry_grass": {}, "tall_grass": { "grass": true, "texture": "tall_grass_top" @@ -2024,6 +2032,8 @@ "texture": "target_top" }, "terracotta": {}, + "test_block": null, + "test_instance_block": null, "tinted_glass": {}, "tnt": { "texture": "tnt_top" @@ -2288,6 +2298,7 @@ "white_tulip": null, "white_wall_banner": null, "white_wool": {}, + "wildflowers": null, "wither_rose": null, "wither_skeleton_skull": null, "wither_skeleton_wall_skull": null, diff --git a/src/core/common.rs b/src/core/common.rs index 06a3277..d285f4c 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -26,7 +26,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(6); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(7); /// MinedMap map tile data version number /// @@ -38,7 +38,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(4); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(5); /// MinedMap mipmap data version number /// From 69b62576ea805c2674144f5f600ad00fecdbb111 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Apr 2025 18:37:36 +0200 Subject: [PATCH 142/152] world/chunk: fix new Rust 1.86 clippy warning --- src/world/chunk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 311fca8..aadf882 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -419,7 +419,7 @@ impl<'a> Iterator for SectionIter<'a> { } fn last(mut self) -> Option { - self.with_iter(|iter| iter.last()) + self.next_back() } } From dd56e842b526774aa0d1bba035b7da6d7cdd57e9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Apr 2025 18:31:41 +0200 Subject: [PATCH 143/152] ci: update to Rust 1.86 There is no official 1.86 Docker image yet. --- .github/workflows/MinedMap.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index ece4e50..4dbb5d2 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -48,7 +48,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85.1' + toolchain: '1.86' components: rustfmt - run: cargo fmt --all -- --check @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85.1' + toolchain: '1.86' components: clippy - uses: swatinem/rust-cache@v2 - uses: actions-rs/clippy-check@v1 @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85.1' + toolchain: '1.86' components: rust-docs - uses: swatinem/rust-cache@v2 - run: cargo doc --workspace --no-deps --document-private-items @@ -87,7 +87,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85.1' + toolchain: '1.86' - uses: swatinem/rust-cache@v2 - run: cargo test --workspace - run: cargo test --workspace --no-default-features @@ -127,7 +127,7 @@ jobs: - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.85.1' + toolchain: '1.86' targets: '${{ matrix.target }}' - uses: swatinem/rust-cache@v2 From ca880ab3b457a12f775e83a43b3ede5804f7bc63 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Apr 2025 18:26:49 +0200 Subject: [PATCH 144/152] world/text_value: do not fall back to NBT deserialization after DataVersion 4290 An invalid JSON string should not be emitted verbatim; ignore the content instead. Also increment entity meta version, which had been forgotten in the previous commit. --- src/core/common.rs | 2 +- src/world/text_value.rs | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index d285f4c..45b541c 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -48,7 +48,7 @@ pub const MIPMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// MinedMap processed entity data version number /// /// Increase when entity collection changes bacause of code changes. -pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(2); +pub const ENTITIES_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(3); /// Coordinate pair of a generated tile /// diff --git a/src/world/text_value.rs b/src/world/text_value.rs index 75defc4..3de6593 100644 --- a/src/world/text_value.rs +++ b/src/world/text_value.rs @@ -176,15 +176,20 @@ pub struct TextValue(pub fastnbt::Value); impl TextValue { /// Deserializes a [TextValue] into a [DeserializedText] pub fn deserialize(&self, data_version: u32) -> DeserializedText { + // TODO: Improve error handling + // + // Unfortunately, there are a number of weird ways an empty sign coould + // be encoded (for example a compound with an "" key), so for now we + // simply interpret undecodable data as empty. if data_version < 4290 { - if let fastnbt::Value::String(json) = &self.0 { - if let Ok(content) = serde_json::from_str(json) { - return content; - } - } - } + let fastnbt::Value::String(json) = &self.0 else { + return DeserializedText::default(); + }; - fastnbt::from_value(&self.0).unwrap_or_default() + serde_json::from_str(json).unwrap_or_default() + } else { + fastnbt::from_value(&self.0).unwrap_or_default() + } } } From ec4fd7986497f9d1e03626c4044ebf07cd561271 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jun 2025 17:04:15 +0200 Subject: [PATCH 145/152] Update dependencies --- Cargo.lock | 394 ++++++++++++++++++++++++++++++----------------------- Cargo.toml | 4 +- 2 files changed, 228 insertions(+), 170 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9f14f8..8187256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" @@ -34,9 +34,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -49,56 +49,56 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -106,7 +106,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -137,15 +137,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bytemuck" -version = "1.22.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" [[package]] name = "byteorder" @@ -161,9 +161,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "cc" -version = "1.2.17" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -178,15 +178,15 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "clap" -version = "4.5.35" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -207,9 +207,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -219,15 +219,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "crc32fast" @@ -291,18 +291,18 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", @@ -317,12 +317,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -337,6 +337,12 @@ dependencies = [ "serde_bytes", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fdeflate" version = "0.3.7" @@ -360,9 +366,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "libz-rs-sys", @@ -423,9 +429,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -461,15 +467,15 @@ dependencies = [ [[package]] name = "glam" -version = "0.30.1" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf3aa70d918d2b234126ff4f850f628f172542bf0603ded26b8ee36e5e22d5f9" +checksum = "50a99dbe56b72736564cfa4b85bf9a33079f16ae8b74983ab06af3b1a3696b11" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", "equivalent", @@ -484,9 +490,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "humantime" @@ -509,9 +515,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b" dependencies = [ "byteorder-lite", "quick-error", @@ -519,9 +525,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -533,7 +539,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "inotify-sys", "libc", ] @@ -580,9 +586,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.0.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -606,41 +612,41 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", "redox_syscall", ] [[package]] name = "libz-rs-sys" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a" +checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221" dependencies = [ "zlib-rs", ] [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -654,18 +660,18 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" -version = "0.13.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" +checksum = "0281c2e25e62316a5c9d98f2d2e9e95a37841afdaf4383c177dbb5c1dfab0568" dependencies = [ "hashbrown", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "minedmap" @@ -741,9 +747,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", "simd-adler32", @@ -751,14 +757,14 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -767,7 +773,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "filetime", "fsevent-sys", "inotify", @@ -816,9 +822,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ "hermit-abi", "libc", @@ -839,6 +845,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "overload" version = "0.1.1" @@ -847,9 +859,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -857,42 +869,43 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] name = "phf" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ "phf_macros", "phf_shared", + "serde", ] [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "2cbb1126afed61dd6368748dae63b1ee7dc480191c6262a3b4ff1e29d86a6c5b" dependencies = [ + "fastrand", "phf_shared", - "rand", ] [[package]] name = "phf_macros" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "d713258393a82f091ead52047ca779d37e5766226d009de21696c4e667044368" dependencies = [ "phf_generator", "phf_shared", @@ -903,9 +916,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] @@ -943,9 +956,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -967,24 +980,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rayon" @@ -1008,11 +1006,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -1046,9 +1044,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -1058,11 +1056,11 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys", @@ -1160,18 +1158,15 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "strsim" @@ -1181,9 +1176,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1202,12 +1197,11 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -1232,9 +1226,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "parking_lot", @@ -1254,9 +1248,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", @@ -1265,9 +1259,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -1340,9 +1334,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -1384,22 +1378,22 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", ] [[package]] @@ -1408,14 +1402,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1424,62 +1434,110 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] name = "zlib-rs" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8" +checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 34e5619..2f7a483 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ git-version = "0.3.5" humantime = "2.1.0" image = { version = "0.25.1", default-features = false, features = ["png", "webp"] } indexmap = "2.0.0" -lru = "0.13.0" +lru = "0.15.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.2.0", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.7.0", path = "crates/resource" } @@ -56,7 +56,7 @@ minedmap-types = { version = "0.2.0", path = "crates/types" } notify = "8.0.0" num-integer = "0.1.45" num_cpus = "1.16.0" -phf = { version = "0.11.2", features = ["macros"] } +phf = { version = "0.12.1", features = ["macros"] } rayon = "1.7.0" regex = "1.10.2" rustc-hash = "2.0.0" From 64e7375f2fe171d5d9226f5ab6b938c5316aa198 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jun 2025 17:05:59 +0200 Subject: [PATCH 146/152] Fix 1.88.0 clippy warnings --- crates/nbt/examples/nbtdump.rs | 2 +- crates/nbt/examples/regiondump.rs | 2 +- crates/nbt/src/region.rs | 6 +++--- src/core/common.rs | 4 ++-- src/core/region_processor.rs | 11 ++++------- src/core/tile_renderer.rs | 6 +++--- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/crates/nbt/examples/nbtdump.rs b/crates/nbt/examples/nbtdump.rs index 66aaa2a..8b61693 100644 --- a/crates/nbt/examples/nbtdump.rs +++ b/crates/nbt/examples/nbtdump.rs @@ -20,7 +20,7 @@ fn main() -> Result<()> { let args = Args::parse(); let value: fastnbt::Value = minedmap_nbt::data::from_file(args.file.as_path())?; - println!("{:#x?}", value); + println!("{value:#x?}"); Ok(()) } diff --git a/crates/nbt/examples/regiondump.rs b/crates/nbt/examples/regiondump.rs index 9315022..7cece8c 100644 --- a/crates/nbt/examples/regiondump.rs +++ b/crates/nbt/examples/regiondump.rs @@ -21,7 +21,7 @@ fn main() -> Result<()> { minedmap_nbt::region::from_file(args.file.as_path())?.foreach_chunk( |coords, value: fastnbt::Value| { - println!("Chunk {:?}: {:#x?}", coords, value); + println!("Chunk {coords:?}: {value:#x?}"); Ok(()) }, ) diff --git a/crates/nbt/src/region.rs b/crates/nbt/src/region.rs index 1325919..6a79a39 100644 --- a/crates/nbt/src/region.rs +++ b/crates/nbt/src/region.rs @@ -124,7 +124,7 @@ impl Region { let mut len_buf = [0u8; 4]; reader .read_exact(&mut len_buf) - .with_context(|| format!("Failed to read length for chunk {:?}", coords))?; + .with_context(|| format!("Failed to read length for chunk {coords:?}"))?; let byte_len = u32::from_be_bytes(len_buf) as usize; if byte_len < 1 || byte_len > (len as usize) * BLOCKSIZE - 4 { bail!("Invalid length for chunk {:?}", coords); @@ -133,9 +133,9 @@ impl Region { let mut buffer = vec![0; byte_len]; reader .read_exact(&mut buffer) - .with_context(|| format!("Failed to read data for chunk {:?}", coords))?; + .with_context(|| format!("Failed to read data for chunk {coords:?}"))?; let chunk = decode_chunk(&buffer) - .with_context(|| format!("Failed to decode data for chunk {:?}", coords))?; + .with_context(|| format!("Failed to decode data for chunk {coords:?}"))?; f(coords, chunk)?; } diff --git a/src/core/common.rs b/src/core/common.rs index 45b541c..3f3e69d 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -237,7 +237,7 @@ impl Config { fn sign_transform(splitter: &Regex, transform: &str) -> Result<(Regex, String)> { let captures = splitter .captures(transform) - .with_context(|| format!("Invalid transform pattern '{}'", transform))?; + .with_context(|| format!("Invalid transform pattern '{transform}'"))?; let regexp = Regex::new(&captures[1])?; let replacement = captures[2].to_string(); Ok((regexp, replacement)) @@ -275,7 +275,7 @@ impl Config { TileKind::Map => "map", TileKind::Lightmap => "light", }; - let dir = format!("{}/{}", prefix, level); + let dir = format!("{prefix}/{level}"); [&self.output_dir, Path::new(&dir)].iter().collect() } diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index e638342..74939bd 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -228,7 +228,7 @@ impl<'a> SingleRegionProcessor<'a> { ) -> Result<()> { let (chunk, has_unknown) = world::chunk::Chunk::new(&chunk_data, self.block_types, self.biome_types) - .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; + .with_context(|| format!("Failed to decode chunk {chunk_coords:?}"))?; data.has_unknown |= has_unknown; if self.output_needed || self.lightmap_needed { @@ -238,7 +238,7 @@ impl<'a> SingleRegionProcessor<'a> { block_light, depths, }) = world::layer::top_layer(&mut data.biome_list, &chunk) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + .with_context(|| format!("Failed to process chunk {chunk_coords:?}"))? { if self.output_needed { data.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { @@ -257,10 +257,7 @@ impl<'a> SingleRegionProcessor<'a> { if self.entities_needed { let mut block_entities = chunk.block_entities().with_context(|| { - format!( - "Failed to process block entities for chunk {:?}", - chunk_coords, - ) + format!("Failed to process block entities for chunk {chunk_coords:?}") })?; data.entities.block_entities.append(&mut block_entities); } @@ -407,7 +404,7 @@ impl<'a> RegionProcessor<'a> { self.collect_regions()?.par_iter().try_for_each(|&coords| { let ret = self .process_region(coords) - .with_context(|| format!("Failed to process region {:?}", coords))?; + .with_context(|| format!("Failed to process region {coords:?}"))?; if ret != Status::ErrorMissing { region_send.send(coords).unwrap(); diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 9d7e188..0b534b8 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -249,7 +249,7 @@ impl<'a> TileRenderer<'a> { .filter(|entry| self.region_set.contains(entry)) }) .try_map(|entry| self.processed_source(entry)) - .with_context(|| format!("Region {:?} from previous step must exist", coords))?; + .with_context(|| format!("Region {coords:?} from previous step must exist"))?; let max_timestamp = *sources .iter() @@ -293,7 +293,7 @@ impl<'a> TileRenderer<'a> { let region_group = self .rt .block_on(self.load_region_group(processed_paths)) - .with_context(|| format!("Region {:?} from previous step must be loadable", coords))?; + .with_context(|| format!("Region {coords:?} from previous step must be loadable"))?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion_group); @@ -325,7 +325,7 @@ impl<'a> TileRenderer<'a> { .map(|&coords| { anyhow::Ok(usize::from( self.render_tile(coords) - .with_context(|| format!("Failed to render tile {:?}", coords))?, + .with_context(|| format!("Failed to render tile {coords:?}"))?, )) }) .try_reduce(|| 0, |a, b| Ok(a + b))?; From 6a2f5356d90959a2d2664383975cee88fcdb930a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jun 2025 17:26:59 +0200 Subject: [PATCH 147/152] ci, docker: update to Rust 1.88.0 --- .github/workflows/MinedMap.yml | 10 +++++----- Dockerfile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 4dbb5d2..a0e58cf 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -48,7 +48,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.86' + toolchain: '1.88' components: rustfmt - run: cargo fmt --all -- --check @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.86' + toolchain: '1.88' components: clippy - uses: swatinem/rust-cache@v2 - uses: actions-rs/clippy-check@v1 @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.86' + toolchain: '1.88' components: rust-docs - uses: swatinem/rust-cache@v2 - run: cargo doc --workspace --no-deps --document-private-items @@ -87,7 +87,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.86' + toolchain: '1.88' - uses: swatinem/rust-cache@v2 - run: cargo test --workspace - run: cargo test --workspace --no-default-features @@ -127,7 +127,7 @@ jobs: - uses: dtolnay/rust-toolchain@master with: - toolchain: '1.86' + toolchain: '1.88' targets: '${{ matrix.target }}' - uses: swatinem/rust-cache@v2 diff --git a/Dockerfile b/Dockerfile index ad36c79..4b9de31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/rust:1.85.1-alpine AS builder +FROM docker.io/library/rust:1.88.0-alpine AS builder WORKDIR /build RUN apk add --no-cache build-base tini-static From 19355d8f64732de0be43e736556f5814cfaa4159 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jun 2025 23:29:02 +0200 Subject: [PATCH 148/152] README.md: add link to minecraft_map_marker project --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 952163f..6402d21 100644 --- a/README.md +++ b/README.md @@ -120,3 +120,8 @@ cargo install --git 'https://github.com/neocturne/MinedMap.git' If you are looking for the older C++ implementation of the MinedMap tile renderer, see the [v1.19.1](https://github.com/neocturne/MinedMap/tree/v1.19.1) tag. +## See also + +Other projects using MinedMap: + +- [minecraft\_map\_marker](https://github.com/christopher-besch/minecraft_map_marker) From 04aeacbfd41a2b49c84d8cd5710406bf8e0d762a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jun 2025 23:53:56 +0200 Subject: [PATCH 149/152] resource: add Minecraft 1.21.6 Dried Ghast block type As Minecraft 1.21.7 is a hotfix release with no new block types or biomes, it is supported as well. --- CHANGELOG.md | 2 +- README.md | 2 +- crates/resource/src/block_types.rs | 10 ++++++++++ resource/blocks.json | 3 +++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f96ddca..94dbb8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Added -- Added support for Minecraft 1.21.5 +- Added support for Minecraft 1.21.5 to 1.21.7 Added new block types and handling for changed sign text storage format. diff --git a/README.md b/README.md index 6402d21..cd30c8b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ * Render beautiful maps of your [Minecraft](https://minecraft.net/) worlds! * Put them on a webserver and view them in your browser! -* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21.4 (no mod installation required!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.21.7 (no mod installation required!) * Illumination layer: the world at night * Fast: create a full map for a huge 3GB savegame in less than 5 minutes in single-threaded operation * Multi-threading support: pass `-j N` to the renderer to use `N` parallel threads for generation diff --git a/crates/resource/src/block_types.rs b/crates/resource/src/block_types.rs index 044a153..9419690 100644 --- a/crates/resource/src/block_types.rs +++ b/crates/resource/src/block_types.rs @@ -3508,6 +3508,16 @@ pub const BLOCK_TYPES: &[(&str, ConstBlockType)] = &[ sign_material: None, }, ), + ( + "dried_ghast", + ConstBlockType { + block_color: BlockColor { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([179, 168, 168]), + }, + sign_material: None, + }, + ), ( "dried_kelp_block", ConstBlockType { diff --git a/resource/blocks.json b/resource/blocks.json index caf6f8a..15dae2b 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -720,6 +720,9 @@ "dragon_egg": {}, "dragon_head": null, "dragon_wall_head": null, + "dried_ghast": { + "texture": "dried_ghast_hydration_1_top" + }, "dried_kelp_block": { "texture": "dried_kelp_top" }, From 8278185c9c6dff03838423482321d39425eee4a5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jun 2025 22:00:59 +0200 Subject: [PATCH 150/152] core: update region and lightmap version The versions need to be updated for the new block type. --- src/core/common.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 3f3e69d..094d567 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -26,7 +26,7 @@ use crate::{ /// /// Increase when the generation of processed regions from region data changes /// (usually because of updated resource data) -pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(7); +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(8); /// MinedMap map tile data version number /// @@ -38,7 +38,7 @@ pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// /// Increase when the generation of lightmap tiles from region data changes /// (usually because of updated resource data) -pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(5); +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(6); /// MinedMap mipmap data version number /// From 190b92b68d474db18a406146c0c2819439b274c4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jun 2025 22:07:55 +0200 Subject: [PATCH 151/152] minedmap-resource 0.8.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8187256..953a4a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,7 +730,7 @@ dependencies = [ [[package]] name = "minedmap-resource" -version = "0.7.0" +version = "0.8.0" dependencies = [ "bincode", "enumflags2", diff --git a/Cargo.toml b/Cargo.toml index 2f7a483..39664f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ indexmap = "2.0.0" lru = "0.15.0" minedmap-default-alloc = { version = "0.1.0", path = "crates/default-alloc", optional = true } minedmap-nbt = { version = "0.2.0", path = "crates/nbt", default-features = false } -minedmap-resource = { version = "0.7.0", path = "crates/resource" } +minedmap-resource = { version = "0.8.0", path = "crates/resource" } minedmap-types = { version = "0.2.0", path = "crates/types" } notify = "8.0.0" num-integer = "0.1.45" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 1257a90..b59492c 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-resource" -version = "0.7.0" +version = "0.8.0" description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true From f0ef6d318983580e99082822b965a68d585d4e16 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jun 2025 22:08:16 +0200 Subject: [PATCH 152/152] minedmap 2.6.0 --- CHANGELOG.md | 5 ++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94dbb8b..f1f0234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.6.0] - 2025-06-30 + ### Added - Added support for Minecraft 1.21.5 to 1.21.7 @@ -194,7 +196,8 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.5.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.6.0...HEAD +[2.6.0]: https://github.com/neocturne/MinedMap/compare/v2.5.0...v2.6.0 [2.5.0]: https://github.com/neocturne/MinedMap/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/neocturne/MinedMap/compare/v2.3.1...v2.4.0 [2.3.1]: https://github.com/neocturne/MinedMap/compare/v2.3.0...v2.3.1 diff --git a/Cargo.lock b/Cargo.lock index 953a4a3..a000b9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -675,7 +675,7 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "minedmap" -version = "2.5.0" +version = "2.6.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 39664f7..f0c2bc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ pre-release-commit-message = "{{crate_name}} {{version}}" [package] name = "minedmap" -version = "2.5.0" +version = "2.6.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true