From 367078178f2cdfb3f21eeae00bd0ef3a946a7a2d Mon Sep 17 00:00:00 2001 From: Aaron Webster Date: Wed, 16 Sep 2020 18:14:09 -0700 Subject: [PATCH 001/460] Change BlockType from struct to class Fixes the -Wmismatched-tags compilation warning. --- src/Resource/BlockType.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resource/BlockType.hpp b/src/Resource/BlockType.hpp index 24a46c3..a551830 100644 --- a/src/Resource/BlockType.hpp +++ b/src/Resource/BlockType.hpp @@ -40,7 +40,7 @@ namespace Resource { #define BLOCK_SPRUCE (1u << 4) #define BLOCK_WATER (1u << 5) -struct BlockType { +class BlockType { private: static const std::unordered_map Types; From 07e039d442c18bf21dff9c45a5b5bd307d9a11bb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 13 Feb 2021 10:19:29 +0100 Subject: [PATCH 002/460] CMakeLists.txt: update CMake version requirement to remove future compat warning --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cc6467..362fa58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.4) +cmake_minimum_required(VERSION 2.8.12) project(MINEDMAP CXX) From 0ebc895ec068e9b5de7226e7bd87138fe5748567 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 12 Feb 2021 23:05:07 +0100 Subject: [PATCH 003/460] Info: print concise JSON Reduce size by removing pretty-printing --- src/Info.cpp | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Info.cpp b/src/Info.cpp index eef2b0e..a40dd56 100644 --- a/src/Info.cpp +++ b/src/Info.cpp @@ -43,52 +43,52 @@ void Info::writeJSON(const char *filename) const { return; } - std::fprintf(f, "{\n"); - std::fprintf(f, " \"mipmaps\" : [\n"); + std::fprintf(f, "{"); + std::fprintf(f, "\"mipmaps\":["); for (size_t level = 0; level < regions.size(); level++) { int minX, maxX, minZ, maxZ; std::tie(minX, maxX, minZ, maxZ) = getBounds(level); - std::fprintf(f, " {\n"); - std::fprintf(f, " \"info\" : {\n"); - std::fprintf(f, " \"minX\" : %i,\n", minX); - std::fprintf(f, " \"maxX\" : %i,\n", maxX); - std::fprintf(f, " \"minZ\" : %i,\n", minZ); - std::fprintf(f, " \"maxZ\" : %i\n", maxZ); - std::fprintf(f, " },\n"); - std::fprintf(f, " \"regions\" : [\n"); + std::fprintf(f, "{"); + std::fprintf(f, "\"info\":{"); + std::fprintf(f, "\"minX\":%i,", minX); + std::fprintf(f, "\"maxX\":%i,", maxX); + std::fprintf(f, "\"minZ\":%i,", minZ); + std::fprintf(f, "\"maxZ\":%i", maxZ); + std::fprintf(f, "},"); + std::fprintf(f, "\"regions\":["); for (int z = minZ; z <= maxZ; z++) { - std::fprintf(f, " ["); + std::fprintf(f, "["); for (int x = minX; x <= maxX; x++) { std::fprintf(f, "%s", regions[level].count(std::make_pair(x, z)) ? "true" : "false"); if (x < maxX) - std::fprintf(f, ", "); + std::fprintf(f, ","); } if (z < maxZ) - std::fprintf(f, "],\n"); + std::fprintf(f, "],"); else - std::fprintf(f, "]\n"); + std::fprintf(f, "]"); } - std::fprintf(f, " ]\n"); + std::fprintf(f, "]"); if (level < regions.size() - 1) - std::fprintf(f, " },\n"); + std::fprintf(f, "},"); else - std::fprintf(f, " }\n"); + std::fprintf(f, "}"); } - std::fprintf(f, " ],\n"); - std::fprintf(f, " \"spawn\" : {\n"); - std::fprintf(f, " \"x\" : %li,\n", (long)spawnX); - std::fprintf(f, " \"z\" : %li\n", (long)spawnZ); - std::fprintf(f, " }\n"); - std::fprintf(f, "}\n"); + std::fprintf(f, "],"); + std::fprintf(f, "\"spawn\":{"); + std::fprintf(f, "\"x\":%li,", (long)spawnX); + std::fprintf(f, "\"z\":%li", (long)spawnZ); + std::fprintf(f, "}"); + std::fprintf(f, "}"); std::fclose(f); From d2802b73f5eff825a4873d3b4577f14364cba856 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 12 Feb 2021 23:40:24 +0100 Subject: [PATCH 004/460] Info: make tile existence map mor efficient for sparse worlds Explicitly list the coordinates where tiles exist instead of including a full array with the size of the bounding box. --- src/Info.cpp | 38 ++++++++++++++++++++++---------------- src/Info.hpp | 10 ++++++++-- viewer/MinedMap.js | 21 ++++++++++++++++++++- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/Info.cpp b/src/Info.cpp index a40dd56..913c0f2 100644 --- a/src/Info.cpp +++ b/src/Info.cpp @@ -47,6 +47,9 @@ void Info::writeJSON(const char *filename) const { std::fprintf(f, "\"mipmaps\":["); for (size_t level = 0; level < regions.size(); level++) { + if (level != 0) + std::fprintf(f, ","); + int minX, maxX, minZ, maxZ; std::tie(minX, maxX, minZ, maxZ) = getBounds(level); @@ -57,30 +60,33 @@ void Info::writeJSON(const char *filename) const { std::fprintf(f, "\"minZ\":%i,", minZ); std::fprintf(f, "\"maxZ\":%i", maxZ); std::fprintf(f, "},"); - std::fprintf(f, "\"regions\":["); + std::fprintf(f, "\"regions\":{"); - for (int z = minZ; z <= maxZ; z++) { - std::fprintf(f, "["); + bool first_z = true; + for (const auto &item : regions[level]) { + if (!first_z) + std::fprintf(f, ","); + first_z = false; - for (int x = minX; x <= maxX; x++) { - std::fprintf(f, "%s", regions[level].count(std::make_pair(x, z)) ? "true" : "false"); + int z = item.first; + const std::set &z_regions = item.second; - if (x < maxX) + std::fprintf(f, "\"%d\":[", z); + + bool first_x = true; + for (int x : z_regions) { + if (!first_x) std::fprintf(f, ","); + first_x = false; + + + std::fprintf(f, "%d", x); } - if (z < maxZ) - std::fprintf(f, "],"); - else - std::fprintf(f, "]"); + std::fprintf(f, "]"); } - std::fprintf(f, "]"); - - if (level < regions.size() - 1) - std::fprintf(f, "},"); - else - std::fprintf(f, "}"); + std::fprintf(f, "}}"); } std::fprintf(f, "],"); diff --git a/src/Info.hpp b/src/Info.hpp index 4bc1222..bccabdb 100644 --- a/src/Info.hpp +++ b/src/Info.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,7 @@ namespace MinedMap { class Info { private: - std::vector>> regions; + std::vector>> regions; std::vector> bounds; int32_t spawnX, spawnZ; @@ -54,7 +55,12 @@ public: } void addRegion(int x, int z, size_t level) { - regions[level].insert(std::make_pair(x, z)); + auto &level_r = regions[level]; + auto z_regions = level_r.emplace( + std::piecewise_construct, + std::make_tuple(z), + std::make_tuple()).first; + z_regions->second.insert(x); std::tuple &b = bounds[level]; diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index f6f444e..8eb4b1f 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -1,3 +1,22 @@ +// bsearch-based array element check +function contains(array, elem) { + var min = 0, max = array.length, i, cur; + + while (min < max) { + i = min + Math.floor((max-min)/2); + cur = array[i]; + + if (cur === elem) + return true; + else if (cur < elem) + min = i + 1; + else + max = i; + } + + return false; +} + var MinedMapLayer = L.GridLayer.extend({ initialize: function (mipmaps, layer) { this.mipmaps = mipmaps; @@ -43,7 +62,7 @@ var MinedMapLayer = L.GridLayer.extend({ if (coords.x >= mipmap.info.minX && coords.x <= mipmap.info.maxX && coords.y >= mipmap.info.minZ && coords.y <= mipmap.info.maxZ && - mipmap.regions[coords.y-mipmap.info.minZ][coords.x-mipmap.info.minX]) + contains(mipmap.regions[coords.y] || [], coords.x)) tile.src = 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; if (z === 0) From cbc4a946c63bc04fcb920f866f858013a87c1c8b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 12 Feb 2021 23:43:20 +0100 Subject: [PATCH 005/460] Info: rename mipmap "info" key to "bounds" --- src/Info.cpp | 2 +- viewer/MinedMap.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Info.cpp b/src/Info.cpp index 913c0f2..55c1156 100644 --- a/src/Info.cpp +++ b/src/Info.cpp @@ -54,7 +54,7 @@ void Info::writeJSON(const char *filename) const { std::tie(minX, maxX, minZ, maxZ) = getBounds(level); std::fprintf(f, "{"); - std::fprintf(f, "\"info\":{"); + std::fprintf(f, "\"bounds\":{"); std::fprintf(f, "\"minX\":%i,", minX); std::fprintf(f, "\"maxX\":%i,", maxX); std::fprintf(f, "\"minZ\":%i,", minZ); diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 8eb4b1f..0ced720 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -60,8 +60,8 @@ var MinedMapLayer = L.GridLayer.extend({ var mipmap = this.mipmaps[z]; - if (coords.x >= mipmap.info.minX && coords.x <= mipmap.info.maxX && - coords.y >= mipmap.info.minZ && coords.y <= mipmap.info.maxZ && + if (coords.x >= mipmap.bounds.minX && coords.x <= mipmap.bounds.maxX && + coords.y >= mipmap.bounds.minZ && coords.y <= mipmap.bounds.maxZ && contains(mipmap.regions[coords.y] || [], coords.x)) tile.src = 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; @@ -190,8 +190,8 @@ window.createMap = function () { maxZoom: 3, crs: L.CRS.Simple, maxBounds: [ - [-512*(mipmaps[0].info.maxZ+1), 512*mipmaps[0].info.minX], - [-512*mipmaps[0].info.minZ, 512*(mipmaps[0].info.maxX+1)], + [-512*(mipmaps[0].bounds.maxZ+1), 512*mipmaps[0].bounds.minX], + [-512*mipmaps[0].bounds.minZ, 512*(mipmaps[0].bounds.maxX+1)], ], }); From c06af49068ec0f4d3ac5702b8c6a74626d68ddd2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 13 Feb 2021 00:34:33 +0100 Subject: [PATCH 006/460] Info: restructure mipmap level data structure --- src/Info.cpp | 10 ++++++---- src/Info.hpp | 25 ++++++++++++++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Info.cpp b/src/Info.cpp index 55c1156..9d9d751 100644 --- a/src/Info.cpp +++ b/src/Info.cpp @@ -46,12 +46,14 @@ void Info::writeJSON(const char *filename) const { std::fprintf(f, "{"); std::fprintf(f, "\"mipmaps\":["); - for (size_t level = 0; level < regions.size(); level++) { - if (level != 0) + bool first_level = true; + for (const auto &level : levels) { + if (!first_level) std::fprintf(f, ","); + first_level = false; int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = getBounds(level); + std::tie(minX, maxX, minZ, maxZ) = level.bounds; std::fprintf(f, "{"); std::fprintf(f, "\"bounds\":{"); @@ -63,7 +65,7 @@ void Info::writeJSON(const char *filename) const { std::fprintf(f, "\"regions\":{"); bool first_z = true; - for (const auto &item : regions[level]) { + for (const auto &item : level.regions) { if (!first_z) std::fprintf(f, ","); first_z = false; diff --git a/src/Info.hpp b/src/Info.hpp index bccabdb..fe4950a 100644 --- a/src/Info.hpp +++ b/src/Info.hpp @@ -39,9 +39,14 @@ namespace MinedMap { class Info { +public: + struct Level { + std::map> regions; + std::tuple bounds; + }; + private: - std::vector>> regions; - std::vector> bounds; + std::vector levels; int32_t spawnX, spawnZ; @@ -51,18 +56,18 @@ public: } std::tuple getBounds(size_t level) const { - return bounds[level]; + return levels[level].bounds; } void addRegion(int x, int z, size_t level) { - auto &level_r = regions[level]; - auto z_regions = level_r.emplace( + auto &the_level = levels[level]; + auto z_regions = the_level.regions.emplace( std::piecewise_construct, std::make_tuple(z), std::make_tuple()).first; z_regions->second.insert(x); - std::tuple &b = bounds[level]; + std::tuple &b = the_level.bounds; if (x < std::get<0>(b)) std::get<0>(b) = x; if (x > std::get<1>(b)) std::get<1>(b) = x; @@ -71,12 +76,14 @@ public: } void addMipmapLevel() { - regions.emplace_back(); - bounds.emplace_back(INT_MAX, INT_MIN, INT_MAX, INT_MIN); + levels.emplace_back(Level { + .regions = {}, + .bounds = {INT_MAX, INT_MIN, INT_MAX, INT_MIN}, + }); } size_t getMipmapLevel() const { - return regions.size()-1; + return levels.size()-1; } void setSpawn(const std::pair &v) { From 9ac3b00b6e25d3a47208e8410c55b4545beb76a3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 13 Feb 2021 09:57:45 +0100 Subject: [PATCH 007/460] Make region iteration more efficient for sparse worlds Do not iterate over each region coordinate in the bounding box. Closes #12 --- src/Info.hpp | 11 ++++++++-- src/MinedMap.cpp | 57 ++++++++++++++++++++++-------------------------- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/Info.hpp b/src/Info.hpp index fe4950a..24f0c0e 100644 --- a/src/Info.hpp +++ b/src/Info.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,8 @@ namespace MinedMap { class Info { public: + typedef std::function RegionVisitor; + struct Level { std::map> regions; std::tuple bounds; @@ -82,8 +85,12 @@ public: }); } - size_t getMipmapLevel() const { - return levels.size()-1; + void visitRegions(size_t level, const RegionVisitor &visitor) const { + for (const auto &item : levels[level].regions) { + int z = item.first; + for (int x : item.second) + visitor(x, z); + } } void setSpawn(const std::pair &v) { diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index f37b96c..4855b6f 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -292,13 +292,9 @@ static void makeBiome(const std::string ®iondir, const std::string &outputdir } static void makeBiomes(const std::string ®iondir, const std::string &outputdir, const Info *info) { - int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0); - - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) - makeBiome(regiondir, outputdir, x, z); - } + info->visitRegions(0, [&] (int x, int z) { + makeBiome(regiondir, outputdir, x, z); + }); } static void makeMap(const std::string ®iondir, const std::string &outputdir, int x, int z) { @@ -356,13 +352,9 @@ static void makeMap(const std::string ®iondir, const std::string &outputdir, } static void makeMaps(const std::string ®iondir, const std::string &outputdir, const Info *info) { - int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0); - - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) - makeMap(regiondir, outputdir, x, z); - } + info->visitRegions(0, [&] (int x, int z) { + makeMap(regiondir, outputdir, x, z); + }); } static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG::Format imageFormat) { @@ -432,29 +424,32 @@ static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG:: return true; } +static int floored_half(int a) { + return (a - (a < 0)) / 2; +} + static void makeMipmaps(const std::string &dir, Info *info) { - int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = info->getBounds(0); + for (size_t level = 0; ; level++) { + int minX, maxX, minZ, maxZ; + std::tie(minX, maxX, minZ, maxZ) = info->getBounds(level); + + if (minX >= -1 && maxX <= 0 && minZ >= -1 && maxZ <= 0) + break; - while (minX < -1 || maxX > 0 || minZ < -1 || maxZ > 0) { info->addMipmapLevel(); - size_t level = info->getMipmapLevel(); - makeDir(dir + "/map/" + format(level)); - makeDir(dir + "/light/" + format(level)); + makeDir(dir + "/map/" + format(level + 1)); + makeDir(dir + "/light/" + format(level + 1)); - minX = (minX-1)/2; - maxX = maxX/2; - minZ = (minZ-1)/2; - maxZ = maxZ/2; + info->visitRegions(level, [&] (int x, int z) { + info->addRegion(floored_half(x), floored_half(z), level + 1); + }); - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) { - if (makeMipmap(dir + "/map", level, x, z, PNG::RGB_ALPHA)) - info->addRegion(x, z, level); + info->visitRegions(level + 1, [&] (int x, int z) { + if (makeMipmap(dir + "/map", level + 1, x, z, PNG::RGB_ALPHA)) + info->addRegion(x, z, level + 1); - makeMipmap(dir + "/light", level, x, z, PNG::GRAY_ALPHA); - } - } + makeMipmap(dir + "/light", level + 1, x, z, PNG::GRAY_ALPHA); + }); } } From 5c55ce81407c381f9de2ff14d682aec481fa2b8d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 22 Jun 2021 23:18:43 +0200 Subject: [PATCH 008/460] resource: add blocklist tool to list and diff the supported block IDs of a Minecraft version --- resource/blocklist.py | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 resource/blocklist.py diff --git a/resource/blocklist.py b/resource/blocklist.py new file mode 100755 index 0000000..d3de297 --- /dev/null +++ b/resource/blocklist.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys + +def blocklist(path): + blockpath = os.path.join(path, 'assets', 'minecraft', 'blockstates') + try: + return map( + lambda filename: filename[:-5], + filter( + lambda filename: filename.endswith('.json'), + os.listdir(blockpath), + ), + ) + except FileNotFoundError: + sys.exit(''' +Path '{}' not found. +Please pass a directory containing the unpacked contents of a JAR of a recent Minecraft version. + '''.strip().format(blockpath)) + +def print_blocklist(path): + for block in sorted(blocklist(path)): + print(block) + +def diff_blocklist(old, new, cmd): + blocks_old = set(blocklist(old)) + blocks_new = set(blocklist(new)) + diff = sorted(blocks_old.symmetric_difference(blocks_new)) + + for block in diff: + if block in blocks_old: + if cmd == 'removed': + print(block) + elif cmd == 'diff': + print('-', block) + else: + if cmd == 'added': + print(block) + elif cmd == 'diff': + print('+', block) + + +parser = argparse.ArgumentParser(description='List block IDs of an unpacked Minecraft JAR, or diff two versions') + +subparsers = parser.add_subparsers(dest='cmd', metavar='COMMAND', required=True) + +parse_list = subparsers.add_parser('list', help='list supported blocks') +parse_list.add_argument('DIR') + +parse_added = subparsers.add_parser('added', help='list added blocks') +parse_added.add_argument('OLD') +parse_added.add_argument('NEW') + +parse_removed = subparsers.add_parser('removed', help='list removed blocks') +parse_removed.add_argument('OLD') +parse_removed.add_argument('NEW') + +parse_removed = subparsers.add_parser('diff', help='diff lists of supported blocks') +parse_removed.add_argument('OLD') +parse_removed.add_argument('NEW') + +args = parser.parse_args() + +if args.cmd == 'list': + print_blocklist(args.DIR) +else: + diff_blocklist(args.OLD, args.NEW, args.cmd) From 73343dede2e24f87b86b45ed0ed771c4040413a4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 24 Jun 2021 17:17:19 +0200 Subject: [PATCH 009/460] resource: add README.md --- resource/README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 resource/README.md diff --git a/resource/README.md b/resource/README.md new file mode 100644 index 0000000..ed35118 --- /dev/null +++ b/resource/README.md @@ -0,0 +1,71 @@ +# Resource management + +## Scripts + +The following scripts can be found in the `resource` directory of this Git +repository. Python 3.8 should be sufficient, older versions may or may not +work. + +- `blocklist.py`: Lists all supported block IDs of an unpacked Minecraft JAR, or diffs the ID lists + of two different versions +- `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 `BlockType.inc` from `colors.json` + +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 + +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 + to do so. On Linux the downloaded JAR archive can be found at + `~/.minecraft/versions/`. +2. Unpack both versions to different directories. The next part assumes that + the unpacked data is stored in `resource/data/old` and `resource/data/new`; + using the respective Minecraft version numbers instead of `old` + and `new` is advisable. +3. Check the added and removed block types using `blocklist.py`: + + ```sh + ./blocklist.py diff data/old data/new + ``` + +4. Append all new block types to `blocks.json`. The following command can be + used to generate the basic JSON structure: + + ```sh + ./blocklist.py added data/old data/new | jq -R -n -S --tab '[inputs] | map({key: ., value: {}}) | from_entries' + ``` + +5. Edit `blocks.json` until the following command passes without errors: + + ```sh + ./extract.py blocks.json data/new/assets/minecraft/textures/block colors.json + ``` + + 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. + + The `water`, `grass` and `foliage` flags control biome-dependent texture color modifiers. + +6. When `colors.json` builds successfully, use the following command to sort + `blocks.json` by block ID: + + ```sh + jq --tab -S < blocks.json > blocks.json.new && mv blocks.json.new blocks.json + ``` + + Then regenerate `colors.json` one last time, so it is sorted as well. + +7. Update the source code with the new block colors: + + ```sh + ./generate.py colors.json ../src/Resource/BlockType.inc + ``` + +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. From 0a42605a2b3146c43a6e9812d75b68250019a5ba Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 23 Jun 2021 22:41:59 +0200 Subject: [PATCH 010/460] Add Minecraft 1.17 block types, update all color values --- resource/blocks.json | 271 ++++++++++++++++++++++++++++++++++++- src/Resource/BlockType.inc | 165 ++++++++++++++++++++-- 2 files changed, 421 insertions(+), 15 deletions(-) diff --git a/resource/blocks.json b/resource/blocks.json index e16d69b..78c0d4c 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -37,6 +37,8 @@ "activator_rail": {}, "air": null, "allium": null, + "amethyst_block": {}, + "amethyst_cluster": {}, "ancient_debris": { "texture": "ancient_debris_top" }, @@ -59,6 +61,10 @@ "attached_pumpkin_stem": { "grass": true }, + "azalea": { + "texture": "azalea_top" + }, + "azalea_leaves": {}, "azure_bluet": null, "bamboo": { "texture": "bamboo_stalk" @@ -85,6 +91,10 @@ "bell": { "texture": "bell_top" }, + "big_dripleaf": { + "texture": "big_dripleaf_top" + }, + "big_dripleaf_stem": null, "birch_button": null, "birch_door": { "texture": "birch_door_top" @@ -122,6 +132,10 @@ }, "black_banner": null, "black_bed": null, + "black_candle": null, + "black_candle_cake": { + "texture": "cake_top" + }, "black_carpet": { "texture": "black_wool" }, @@ -153,6 +167,10 @@ }, "blue_banner": null, "blue_bed": null, + "blue_candle": null, + "blue_candle_cake": { + "texture": "cake_top" + }, "blue_carpet": { "texture": "blue_wool" }, @@ -192,6 +210,10 @@ "bricks": {}, "brown_banner": null, "brown_bed": null, + "brown_candle": null, + "brown_candle_cake": { + "texture": "cake_top" + }, "brown_carpet": { "texture": "brown_wool" }, @@ -216,15 +238,21 @@ "bubble_coral_block": {}, "bubble_coral_fan": null, "bubble_coral_wall_fan": null, + "budding_amethyst": {}, "cactus": { "texture": "cactus_top" }, "cake": { "texture": "cake_top" }, + "calcite": {}, "campfire": { "texture": "campfire_log_lit" }, + "candle": null, + "candle_cake": { + "texture": "cake_top" + }, "carrots": { "texture": "carrots_stage3" }, @@ -238,6 +266,8 @@ "texture": "cauldron_top" }, "cave_air": null, + "cave_vines": {}, + "cave_vines_plant": {}, "chain": null, "chain_command_block": { "texture": "chain_command_block_side" @@ -248,6 +278,7 @@ "chipped_anvil": { "texture": "chipped_anvil_top" }, + "chiseled_deepslate": {}, "chiseled_nether_bricks": {}, "chiseled_polished_blackstone": {}, "chiseled_quartz_block": {}, @@ -264,6 +295,16 @@ "coal_block": {}, "coal_ore": {}, "coarse_dirt": {}, + "cobbled_deepslate": {}, + "cobbled_deepslate_slab": { + "texture": "cobbled_deepslate" + }, + "cobbled_deepslate_stairs": { + "texture": "cobbled_deepslate" + }, + "cobbled_deepslate_wall": { + "texture": "cobbled_deepslate" + }, "cobblestone": {}, "cobblestone_slab": { "texture": "cobblestone" @@ -286,7 +327,11 @@ "texture": "composter_compost" }, "conduit": {}, + "copper_block": {}, + "copper_ore": {}, "cornflower": null, + "cracked_deepslate_bricks": {}, + "cracked_deepslate_tiles": {}, "cracked_nether_bricks": {}, "cracked_polished_blackstone_bricks": {}, "cracked_stone_bricks": {}, @@ -330,6 +375,13 @@ "crimson_trapdoor": {}, "crimson_wall_sign": null, "crying_obsidian": {}, + "cut_copper": {}, + "cut_copper_slab": { + "texture": "cut_copper" + }, + "cut_copper_stairs": { + "texture": "cut_copper" + }, "cut_red_sandstone": { "texture": "red_sandstone_top" }, @@ -344,6 +396,10 @@ }, "cyan_banner": null, "cyan_bed": null, + "cyan_candle": null, + "cyan_candle_cake": { + "texture": "cake_top" + }, "cyan_carpet": { "texture": "cyan_wool" }, @@ -428,6 +484,35 @@ "dead_tube_coral_block": {}, "dead_tube_coral_fan": null, "dead_tube_coral_wall_fan": null, + "deepslate": {}, + "deepslate_brick_slab": { + "texture": "deepslate_bricks" + }, + "deepslate_brick_stairs": { + "texture": "deepslate_bricks" + }, + "deepslate_brick_wall": { + "texture": "deepslate_bricks" + }, + "deepslate_bricks": {}, + "deepslate_coal_ore": {}, + "deepslate_copper_ore": {}, + "deepslate_diamond_ore": {}, + "deepslate_emerald_ore": {}, + "deepslate_gold_ore": {}, + "deepslate_iron_ore": {}, + "deepslate_lapis_ore": {}, + "deepslate_redstone_ore": {}, + "deepslate_tile_slab": { + "texture": "deepslate_tiles" + }, + "deepslate_tile_stairs": { + "texture": "deepslate_tiles" + }, + "deepslate_tile_wall": { + "texture": "deepslate_tiles" + }, + "deepslate_tiles": {}, "detector_rail": {}, "diamond_block": {}, "diamond_ore": {}, @@ -442,6 +527,9 @@ "texture": "diorite" }, "dirt": {}, + "dirt_path": { + "texture": "dirt_path_top" + }, "dispenser": { "texture": "furnace_top" }, @@ -451,6 +539,7 @@ "dried_kelp_block": { "texture": "dried_kelp_top" }, + "dripstone_block": {}, "dropper": { "texture": "furnace_top" }, @@ -483,6 +572,14 @@ "ender_chest": { "texture": "obsidian" }, + "exposed_copper": {}, + "exposed_cut_copper": {}, + "exposed_cut_copper_slab": { + "texture": "exposed_cut_copper" + }, + "exposed_cut_copper_stairs": { + "texture": "exposed_cut_copper" + }, "farmland": { "texture": "farmland_moist" }, @@ -498,6 +595,10 @@ "texture": "fletching_table_top" }, "flower_pot": {}, + "flowering_azalea": { + "texture": "flowering_azalea_top" + }, + "flowering_azalea_leaves": {}, "frosted_ice": { "texture": "frosted_ice_0" }, @@ -509,6 +610,8 @@ "glass_pane": { "texture": "glass_pane_top" }, + "glow_item_frame": null, + "glow_lichen": null, "glowstone": {}, "gold_block": {}, "gold_ore": {}, @@ -528,11 +631,15 @@ "texture": "grass_block_top" }, "grass_path": { - "texture": "grass_path_top" + "texture": "dirt_path_top" }, "gravel": {}, "gray_banner": null, "gray_bed": null, + "gray_candle": null, + "gray_candle_cake": { + "texture": "cake_top" + }, "gray_carpet": { "texture": "gray_wool" }, @@ -549,6 +656,10 @@ "gray_wool": {}, "green_banner": null, "green_bed": null, + "green_candle": null, + "green_candle_cake": { + "texture": "cake_top" + }, "green_carpet": { "texture": "green_wool" }, @@ -566,6 +677,7 @@ "grindstone": { "texture": "grindstone_round" }, + "hanging_roots": {}, "hay_block": { "texture": "hay_block_top" }, @@ -593,6 +705,9 @@ "infested_cracked_stone_bricks": { "texture": "cracked_stone_bricks" }, + "infested_deepslate": { + "texture": "deepslate" + }, "infested_mossy_stone_bricks": { "texture": "mossy_stone_bricks" }, @@ -658,6 +773,7 @@ "lantern": {}, "lapis_block": {}, "lapis_ore": {}, + "large_amethyst_bud": null, "large_fern": { "grass": true, "texture": "large_fern_top" @@ -665,12 +781,20 @@ "lava": { "texture": "lava_still" }, + "lava_cauldron": { + "texture": "cauldron_top" + }, "lectern": { "texture": "lectern_top" }, "lever": null, + "light": null, "light_blue_banner": null, "light_blue_bed": null, + "light_blue_candle": null, + "light_blue_candle_cake": { + "texture": "cake_top" + }, "light_blue_carpet": { "texture": "light_blue_wool" }, @@ -687,6 +811,10 @@ "light_blue_wool": {}, "light_gray_banner": null, "light_gray_bed": null, + "light_gray_candle": null, + "light_gray_candle_cake": { + "texture": "cake_top" + }, "light_gray_carpet": { "texture": "light_gray_wool" }, @@ -704,6 +832,7 @@ "light_weighted_pressure_plate": { "texture": "gold_block" }, + "lightning_rod": null, "lilac": { "texture": "lilac_top" }, @@ -713,6 +842,10 @@ }, "lime_banner": null, "lime_bed": null, + "lime_candle": null, + "lime_candle_cake": { + "texture": "cake_top" + }, "lime_carpet": { "texture": "lime_wool" }, @@ -735,6 +868,10 @@ }, "magenta_banner": null, "magenta_bed": null, + "magenta_candle": null, + "magenta_candle_cake": { + "texture": "cake_top" + }, "magenta_carpet": { "texture": "magenta_wool" }, @@ -752,12 +889,17 @@ "magma_block": { "texture": "magma" }, + "medium_amethyst_bud": null, "melon": { "texture": "melon_top" }, "melon_stem": { "grass": true }, + "moss_block": {}, + "moss_carpet": { + "texture": "moss_block" + }, "mossy_cobblestone": {}, "mossy_cobblestone_slab": { "texture": "mossy_cobblestone" @@ -848,6 +990,10 @@ "obsidian": {}, "orange_banner": null, "orange_bed": null, + "orange_candle": null, + "orange_candle_cake": { + "texture": "cake_top" + }, "orange_carpet": { "texture": "orange_wool" }, @@ -864,6 +1010,14 @@ "orange_wall_banner": null, "orange_wool": {}, "oxeye_daisy": null, + "oxidized_copper": {}, + "oxidized_cut_copper": {}, + "oxidized_cut_copper_slab": { + "texture": "oxidized_cut_copper" + }, + "oxidized_cut_copper_stairs": { + "texture": "oxidized_cut_copper" + }, "packed_ice": {}, "peony": { "texture": "peony_top" @@ -873,6 +1027,10 @@ }, "pink_banner": null, "pink_bed": null, + "pink_candle": null, + "pink_candle_cake": { + "texture": "cake_top" + }, "pink_carpet": { "texture": "pink_wool" }, @@ -899,6 +1057,9 @@ "podzol": { "texture": "podzol_top" }, + "pointed_dripstone": { + "texture": "pointed_dripstone_down_base" + }, "polished_andesite": {}, "polished_andesite_slab": { "texture": "polished_andesite" @@ -933,6 +1094,16 @@ "polished_blackstone_wall": { "texture": "polished_blackstone" }, + "polished_deepslate": {}, + "polished_deepslate_slab": { + "texture": "polished_deepslate" + }, + "polished_deepslate_stairs": { + "texture": "polished_deepslate" + }, + "polished_deepslate_wall": { + "texture": "polished_deepslate" + }, "polished_diorite": {}, "polished_diorite_slab": { "texture": "polished_diorite" @@ -957,6 +1128,9 @@ "potted_allium": { "texture": "allium" }, + "potted_azalea_bush": { + "texture": "azalea_top" + }, "potted_azure_bluet": { "texture": "azure_bluet" }, @@ -997,6 +1171,9 @@ "grass": true, "texture": "fern" }, + "potted_flowering_azalea_bush": { + "texture": "flowering_azalea_top" + }, "potted_jungle_sapling": { "texture": "jungle_sapling" }, @@ -1039,6 +1216,10 @@ "potted_wither_rose": { "texture": "wither_rose" }, + "powder_snow": {}, + "powder_snow_cauldron": { + "texture": "cauldron_top" + }, "powered_rail": {}, "prismarine": {}, "prismarine_brick_slab": { @@ -1065,6 +1246,10 @@ }, "purple_banner": null, "purple_bed": null, + "purple_candle": null, + "purple_candle_cake": { + "texture": "cake_top" + }, "purple_carpet": { "texture": "purple_wool" }, @@ -1099,8 +1284,15 @@ "texture": "quartz_block_top" }, "rail": {}, + "raw_copper_block": {}, + "raw_gold_block": {}, + "raw_iron_block": {}, "red_banner": null, "red_bed": null, + "red_candle": null, + "red_candle_cake": { + "texture": "cake_top" + }, "red_carpet": { "texture": "red_wool" }, @@ -1156,6 +1348,7 @@ "respawn_anchor": { "texture": "respawn_anchor_top" }, + "rooted_dirt": {}, "rose_bush": { "texture": "rose_bush_top" }, @@ -1175,6 +1368,9 @@ "scaffolding": { "texture": "scaffolding_top" }, + "sculk_sensor": { + "texture": "sculk_sensor_top" + }, "sea_lantern": {}, "sea_pickle": {}, "seagrass": null, @@ -1186,12 +1382,15 @@ "skeleton_skull": null, "skeleton_wall_skull": null, "slime_block": {}, + "small_amethyst_bud": null, + "small_dripleaf": null, "smithing_table": { "texture": "smithing_table_top" }, "smoker": { "texture": "smoker_top" }, + "smooth_basalt": {}, "smooth_quartz": { "texture": "quartz_block_top" }, @@ -1240,6 +1439,7 @@ "soul_wall_torch": null, "spawner": {}, "sponge": {}, + "spore_blossom": {}, "spruce_button": null, "spruce_door": { "texture": "spruce_door_top" @@ -1370,6 +1570,7 @@ "texture": "target_top" }, "terracotta": {}, + "tinted_glass": {}, "tnt": { "texture": "tnt_top" }, @@ -1383,6 +1584,7 @@ "tube_coral_block": {}, "tube_coral_fan": null, "tube_coral_wall_fan": null, + "tuff": {}, "turtle_egg": {}, "twisting_vines": {}, "twisting_vines_plant": {}, @@ -1431,6 +1633,65 @@ "texture": "water_still", "water": true }, + "water_cauldron": { + "texture": "cauldron_top" + }, + "waxed_copper_block": { + "texture": "copper_block" + }, + "waxed_cut_copper": { + "texture": "cut_copper" + }, + "waxed_cut_copper_slab": { + "texture": "cut_copper" + }, + "waxed_cut_copper_stairs": { + "texture": "cut_copper" + }, + "waxed_exposed_copper": { + "texture": "exposed_copper" + }, + "waxed_exposed_cut_copper": { + "texture": "exposed_cut_copper" + }, + "waxed_exposed_cut_copper_slab": { + "texture": "exposed_cut_copper" + }, + "waxed_exposed_cut_copper_stairs": { + "texture": "exposed_cut_copper" + }, + "waxed_oxidized_copper": { + "texture": "oxidized_copper" + }, + "waxed_oxidized_cut_copper": { + "texture": "oxidized_cut_copper" + }, + "waxed_oxidized_cut_copper_slab": { + "texture": "oxidized_cut_copper" + }, + "waxed_oxidized_cut_copper_stairs": { + "texture": "oxidized_cut_copper" + }, + "waxed_weathered_copper": { + "texture": "weathered_copper" + }, + "waxed_weathered_cut_copper": { + "texture": "weathered_cut_copper" + }, + "waxed_weathered_cut_copper_slab": { + "texture": "weathered_cut_copper" + }, + "waxed_weathered_cut_copper_stairs": { + "texture": "weathered_cut_copper" + }, + "weathered_copper": {}, + "weathered_cut_copper": {}, + "weathered_cut_copper_slab": { + "texture": "weathered_cut_copper" + }, + "weathered_cut_copper_stairs": { + "texture": "weathered_cut_copper" + }, "weeping_vines": {}, "weeping_vines_plant": {}, "wet_sponge": {}, @@ -1439,6 +1700,10 @@ }, "white_banner": null, "white_bed": null, + "white_candle": null, + "white_candle_cake": { + "texture": "cake_top" + }, "white_carpet": { "texture": "white_wool" }, @@ -1459,6 +1724,10 @@ "wither_skeleton_wall_skull": null, "yellow_banner": null, "yellow_bed": null, + "yellow_candle": null, + "yellow_candle_cake": { + "texture": "cake_top" + }, "yellow_carpet": { "texture": "yellow_wool" }, diff --git a/src/Resource/BlockType.inc b/src/Resource/BlockType.inc index a76fa7a..0489fd9 100644 --- a/src/Resource/BlockType.inc +++ b/src/Resource/BlockType.inc @@ -16,6 +16,8 @@ {"minecraft:activator_rail", {BLOCK_OPAQUE, {115, 87, 74}}}, {"minecraft:air", {0, {0, 0, 0}}}, {"minecraft:allium", {0, {0, 0, 0}}}, +{"minecraft:amethyst_block", {BLOCK_OPAQUE, {133, 97, 191}}}, +{"minecraft:amethyst_cluster", {BLOCK_OPAQUE, {163, 126, 207}}}, {"minecraft:ancient_debris", {BLOCK_OPAQUE, {94, 66, 58}}}, {"minecraft:andesite", {BLOCK_OPAQUE, {136, 136, 136}}}, {"minecraft:andesite_slab", {BLOCK_OPAQUE, {136, 136, 136}}}, @@ -24,6 +26,8 @@ {"minecraft:anvil", {BLOCK_OPAQUE, {72, 72, 72}}}, {"minecraft:attached_melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {141, 142, 141}}}, {"minecraft:attached_pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {139, 139, 139}}}, +{"minecraft:azalea", {BLOCK_OPAQUE, {101, 124, 47}}}, +{"minecraft:azalea_leaves", {BLOCK_OPAQUE, {90, 114, 44}}}, {"minecraft:azure_bluet", {0, {0, 0, 0}}}, {"minecraft:bamboo", {BLOCK_OPAQUE, {93, 144, 19}}}, {"minecraft:bamboo_sapling", {0, {0, 0, 0}}}, @@ -36,6 +40,8 @@ {"minecraft:beehive", {BLOCK_OPAQUE, {180, 146, 90}}}, {"minecraft:beetroots", {BLOCK_OPAQUE, {93, 91, 30}}}, {"minecraft:bell", {BLOCK_OPAQUE, {253, 235, 110}}}, +{"minecraft:big_dripleaf", {BLOCK_OPAQUE, {111, 141, 51}}}, +{"minecraft:big_dripleaf_stem", {0, {0, 0, 0}}}, {"minecraft:birch_button", {0, {0, 0, 0}}}, {"minecraft:birch_door", {BLOCK_OPAQUE, {220, 209, 176}}}, {"minecraft:birch_fence", {BLOCK_OPAQUE, {192, 175, 121}}}, @@ -53,6 +59,8 @@ {"minecraft:birch_wood", {BLOCK_OPAQUE, {216, 215, 210}}}, {"minecraft:black_banner", {0, {0, 0, 0}}}, {"minecraft:black_bed", {0, {0, 0, 0}}}, +{"minecraft:black_candle", {0, {0, 0, 0}}}, +{"minecraft:black_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:black_carpet", {BLOCK_OPAQUE, {20, 21, 25}}}, {"minecraft:black_concrete", {BLOCK_OPAQUE, {8, 10, 15}}}, {"minecraft:black_concrete_powder", {BLOCK_OPAQUE, {25, 26, 31}}}, @@ -70,6 +78,8 @@ {"minecraft:blast_furnace", {BLOCK_OPAQUE, {80, 80, 81}}}, {"minecraft:blue_banner", {0, {0, 0, 0}}}, {"minecraft:blue_bed", {0, {0, 0, 0}}}, +{"minecraft:blue_candle", {0, {0, 0, 0}}}, +{"minecraft:blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:blue_carpet", {BLOCK_OPAQUE, {53, 57, 157}}}, {"minecraft:blue_concrete", {BLOCK_OPAQUE, {44, 46, 143}}}, {"minecraft:blue_concrete_powder", {BLOCK_OPAQUE, {70, 73, 166}}}, @@ -95,6 +105,8 @@ {"minecraft:bricks", {BLOCK_OPAQUE, {150, 97, 83}}}, {"minecraft:brown_banner", {0, {0, 0, 0}}}, {"minecraft:brown_bed", {0, {0, 0, 0}}}, +{"minecraft:brown_candle", {0, {0, 0, 0}}}, +{"minecraft:brown_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:brown_carpet", {BLOCK_OPAQUE, {114, 71, 40}}}, {"minecraft:brown_concrete", {BLOCK_OPAQUE, {96, 59, 31}}}, {"minecraft:brown_concrete_powder", {BLOCK_OPAQUE, {125, 84, 53}}}, @@ -112,18 +124,25 @@ {"minecraft:bubble_coral_block", {BLOCK_OPAQUE, {165, 26, 162}}}, {"minecraft:bubble_coral_fan", {0, {0, 0, 0}}}, {"minecraft:bubble_coral_wall_fan", {0, {0, 0, 0}}}, +{"minecraft:budding_amethyst", {BLOCK_OPAQUE, {132, 96, 186}}}, {"minecraft:cactus", {BLOCK_OPAQUE, {85, 127, 43}}}, {"minecraft:cake", {BLOCK_OPAQUE, {248, 222, 214}}}, +{"minecraft:calcite", {BLOCK_OPAQUE, {223, 224, 220}}}, {"minecraft:campfire", {BLOCK_OPAQUE, {110, 88, 54}}}, +{"minecraft:candle", {0, {0, 0, 0}}}, +{"minecraft:candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:carrots", {BLOCK_OPAQUE, {81, 123, 37}}}, {"minecraft:cartography_table", {BLOCK_OPAQUE, {104, 87, 67}}}, {"minecraft:carved_pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}}, {"minecraft:cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, {"minecraft:cave_air", {0, {0, 0, 0}}}, +{"minecraft:cave_vines", {BLOCK_OPAQUE, {90, 109, 40}}}, +{"minecraft:cave_vines_plant", {BLOCK_OPAQUE, {88, 101, 38}}}, {"minecraft:chain", {0, {0, 0, 0}}}, {"minecraft:chain_command_block", {BLOCK_OPAQUE, {131, 161, 147}}}, {"minecraft:chest", {BLOCK_OPAQUE, {162, 130, 78}}}, {"minecraft:chipped_anvil", {BLOCK_OPAQUE, {72, 72, 72}}}, +{"minecraft:chiseled_deepslate", {BLOCK_OPAQUE, {54, 54, 54}}}, {"minecraft:chiseled_nether_bricks", {BLOCK_OPAQUE, {47, 23, 28}}}, {"minecraft:chiseled_polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}}, {"minecraft:chiseled_quartz_block", {BLOCK_OPAQUE, {231, 226, 218}}}, @@ -134,8 +153,12 @@ {"minecraft:chorus_plant", {BLOCK_OPAQUE, {93, 57, 93}}}, {"minecraft:clay", {BLOCK_OPAQUE, {160, 166, 179}}}, {"minecraft:coal_block", {BLOCK_OPAQUE, {16, 15, 15}}}, -{"minecraft:coal_ore", {BLOCK_OPAQUE, {116, 116, 116}}}, +{"minecraft:coal_ore", {BLOCK_OPAQUE, {105, 105, 105}}}, {"minecraft:coarse_dirt", {BLOCK_OPAQUE, {119, 85, 59}}}, +{"minecraft:cobbled_deepslate", {BLOCK_OPAQUE, {77, 77, 80}}}, +{"minecraft:cobbled_deepslate_slab", {BLOCK_OPAQUE, {77, 77, 80}}}, +{"minecraft:cobbled_deepslate_stairs", {BLOCK_OPAQUE, {77, 77, 80}}}, +{"minecraft:cobbled_deepslate_wall", {BLOCK_OPAQUE, {77, 77, 80}}}, {"minecraft:cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}}, {"minecraft:cobblestone_slab", {BLOCK_OPAQUE, {127, 127, 127}}}, {"minecraft:cobblestone_stairs", {BLOCK_OPAQUE, {127, 127, 127}}}, @@ -146,9 +169,13 @@ {"minecraft:comparator", {BLOCK_OPAQUE, {166, 161, 159}}}, {"minecraft:composter", {BLOCK_OPAQUE, {88, 61, 23}}}, {"minecraft:conduit", {BLOCK_OPAQUE, {159, 139, 113}}}, +{"minecraft:copper_block", {BLOCK_OPAQUE, {192, 107, 79}}}, +{"minecraft:copper_ore", {BLOCK_OPAQUE, {124, 125, 120}}}, {"minecraft:cornflower", {0, {0, 0, 0}}}, +{"minecraft:cracked_deepslate_bricks", {BLOCK_OPAQUE, {64, 64, 65}}}, +{"minecraft:cracked_deepslate_tiles", {BLOCK_OPAQUE, {52, 52, 52}}}, {"minecraft:cracked_nether_bricks", {BLOCK_OPAQUE, {40, 20, 23}}}, -{"minecraft:cracked_polished_blackstone_bricks", {BLOCK_OPAQUE, {43, 37, 43}}}, +{"minecraft:cracked_polished_blackstone_bricks", {BLOCK_OPAQUE, {44, 37, 43}}}, {"minecraft:cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}}, {"minecraft:crafting_table", {BLOCK_OPAQUE, {119, 73, 42}}}, {"minecraft:creeper_head", {0, {0, 0, 0}}}, @@ -170,12 +197,17 @@ {"minecraft:crimson_trapdoor", {BLOCK_OPAQUE, {103, 50, 72}}}, {"minecraft:crimson_wall_sign", {0, {0, 0, 0}}}, {"minecraft:crying_obsidian", {BLOCK_OPAQUE, {32, 10, 60}}}, +{"minecraft:cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}}, +{"minecraft:cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}}, +{"minecraft:cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}}, {"minecraft:cut_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}}, {"minecraft:cut_red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}}, {"minecraft:cut_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:cut_sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:cyan_banner", {0, {0, 0, 0}}}, {"minecraft:cyan_bed", {0, {0, 0, 0}}}, +{"minecraft:cyan_candle", {0, {0, 0, 0}}}, +{"minecraft:cyan_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:cyan_carpet", {BLOCK_OPAQUE, {21, 137, 145}}}, {"minecraft:cyan_concrete", {BLOCK_OPAQUE, {21, 119, 136}}}, {"minecraft:cyan_concrete_powder", {BLOCK_OPAQUE, {36, 147, 157}}}, @@ -228,22 +260,41 @@ {"minecraft:dead_tube_coral_block", {BLOCK_OPAQUE, {130, 123, 119}}}, {"minecraft:dead_tube_coral_fan", {0, {0, 0, 0}}}, {"minecraft:dead_tube_coral_wall_fan", {0, {0, 0, 0}}}, +{"minecraft:deepslate", {BLOCK_OPAQUE, {80, 80, 82}}}, +{"minecraft:deepslate_brick_slab", {BLOCK_OPAQUE, {70, 70, 71}}}, +{"minecraft:deepslate_brick_stairs", {BLOCK_OPAQUE, {70, 70, 71}}}, +{"minecraft:deepslate_brick_wall", {BLOCK_OPAQUE, {70, 70, 71}}}, +{"minecraft:deepslate_bricks", {BLOCK_OPAQUE, {70, 70, 71}}}, +{"minecraft:deepslate_coal_ore", {BLOCK_OPAQUE, {74, 74, 76}}}, +{"minecraft:deepslate_copper_ore", {BLOCK_OPAQUE, {92, 93, 89}}}, +{"minecraft:deepslate_diamond_ore", {BLOCK_OPAQUE, {83, 106, 106}}}, +{"minecraft:deepslate_emerald_ore", {BLOCK_OPAQUE, {78, 104, 87}}}, +{"minecraft:deepslate_gold_ore", {BLOCK_OPAQUE, {115, 102, 78}}}, +{"minecraft:deepslate_iron_ore", {BLOCK_OPAQUE, {106, 99, 94}}}, +{"minecraft:deepslate_lapis_ore", {BLOCK_OPAQUE, {79, 90, 115}}}, +{"minecraft:deepslate_redstone_ore", {BLOCK_OPAQUE, {104, 73, 74}}}, +{"minecraft:deepslate_tile_slab", {BLOCK_OPAQUE, {54, 54, 55}}}, +{"minecraft:deepslate_tile_stairs", {BLOCK_OPAQUE, {54, 54, 55}}}, +{"minecraft:deepslate_tile_wall", {BLOCK_OPAQUE, {54, 54, 55}}}, +{"minecraft:deepslate_tiles", {BLOCK_OPAQUE, {54, 54, 55}}}, {"minecraft:detector_rail", {BLOCK_OPAQUE, {123, 104, 90}}}, {"minecraft:diamond_block", {BLOCK_OPAQUE, {98, 237, 228}}}, -{"minecraft:diamond_ore", {BLOCK_OPAQUE, {125, 142, 141}}}, +{"minecraft:diamond_ore", {BLOCK_OPAQUE, {121, 141, 140}}}, {"minecraft:diorite", {BLOCK_OPAQUE, {188, 188, 188}}}, {"minecraft:diorite_slab", {BLOCK_OPAQUE, {188, 188, 188}}}, {"minecraft:diorite_stairs", {BLOCK_OPAQUE, {188, 188, 188}}}, {"minecraft:diorite_wall", {BLOCK_OPAQUE, {188, 188, 188}}}, {"minecraft:dirt", {BLOCK_OPAQUE, {134, 96, 67}}}, +{"minecraft:dirt_path", {BLOCK_OPAQUE, {148, 121, 65}}}, {"minecraft:dispenser", {BLOCK_OPAQUE, {110, 109, 109}}}, {"minecraft:dragon_egg", {BLOCK_OPAQUE, {12, 9, 15}}}, {"minecraft:dragon_head", {0, {0, 0, 0}}}, {"minecraft:dragon_wall_head", {0, {0, 0, 0}}}, {"minecraft:dried_kelp_block", {BLOCK_OPAQUE, {50, 58, 38}}}, +{"minecraft:dripstone_block", {BLOCK_OPAQUE, {134, 107, 92}}}, {"minecraft:dropper", {BLOCK_OPAQUE, {110, 109, 109}}}, {"minecraft:emerald_block", {BLOCK_OPAQUE, {42, 203, 87}}}, -{"minecraft:emerald_ore", {BLOCK_OPAQUE, {117, 136, 124}}}, +{"minecraft:emerald_ore", {BLOCK_OPAQUE, {108, 136, 115}}}, {"minecraft:enchanting_table", {BLOCK_OPAQUE, {128, 75, 85}}}, {"minecraft:end_gateway", {BLOCK_OPAQUE, {15, 10, 24}}}, {"minecraft:end_portal", {BLOCK_OPAQUE, {15, 10, 24}}}, @@ -255,6 +306,10 @@ {"minecraft:end_stone_brick_wall", {BLOCK_OPAQUE, {218, 224, 162}}}, {"minecraft:end_stone_bricks", {BLOCK_OPAQUE, {218, 224, 162}}}, {"minecraft:ender_chest", {BLOCK_OPAQUE, {15, 10, 24}}}, +{"minecraft:exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}}, +{"minecraft:exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}}, +{"minecraft:exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}}, +{"minecraft:exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}}, {"minecraft:farmland", {BLOCK_OPAQUE, {81, 44, 15}}}, {"minecraft:fern", {0, {0, 0, 0}}}, {"minecraft:fire", {BLOCK_OPAQUE, {211, 140, 53}}}, @@ -264,14 +319,18 @@ {"minecraft:fire_coral_wall_fan", {0, {0, 0, 0}}}, {"minecraft:fletching_table", {BLOCK_OPAQUE, {197, 180, 133}}}, {"minecraft:flower_pot", {BLOCK_OPAQUE, {124, 68, 53}}}, +{"minecraft:flowering_azalea", {BLOCK_OPAQUE, {112, 121, 64}}}, +{"minecraft:flowering_azalea_leaves", {BLOCK_OPAQUE, {99, 111, 60}}}, {"minecraft:frosted_ice", {BLOCK_OPAQUE, {140, 181, 252}}}, {"minecraft:furnace", {BLOCK_OPAQUE, {110, 109, 109}}}, -{"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {56, 43, 38}}}, +{"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {55, 42, 38}}}, {"minecraft:glass", {BLOCK_OPAQUE, {175, 213, 219}}}, {"minecraft:glass_pane", {BLOCK_OPAQUE, {211, 239, 244}}}, +{"minecraft:glow_item_frame", {0, {0, 0, 0}}}, +{"minecraft:glow_lichen", {0, {0, 0, 0}}}, {"minecraft:glowstone", {BLOCK_OPAQUE, {171, 131, 84}}}, {"minecraft:gold_block", {BLOCK_OPAQUE, {246, 208, 61}}}, -{"minecraft:gold_ore", {BLOCK_OPAQUE, {143, 140, 125}}}, +{"minecraft:gold_ore", {BLOCK_OPAQUE, {145, 133, 106}}}, {"minecraft:granite", {BLOCK_OPAQUE, {149, 103, 85}}}, {"minecraft:granite_slab", {BLOCK_OPAQUE, {149, 103, 85}}}, {"minecraft:granite_stairs", {BLOCK_OPAQUE, {149, 103, 85}}}, @@ -282,6 +341,8 @@ {"minecraft:gravel", {BLOCK_OPAQUE, {131, 127, 126}}}, {"minecraft:gray_banner", {0, {0, 0, 0}}}, {"minecraft:gray_bed", {0, {0, 0, 0}}}, +{"minecraft:gray_candle", {0, {0, 0, 0}}}, +{"minecraft:gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:gray_carpet", {BLOCK_OPAQUE, {62, 68, 71}}}, {"minecraft:gray_concrete", {BLOCK_OPAQUE, {54, 57, 61}}}, {"minecraft:gray_concrete_powder", {BLOCK_OPAQUE, {76, 81, 84}}}, @@ -294,6 +355,8 @@ {"minecraft:gray_wool", {BLOCK_OPAQUE, {62, 68, 71}}}, {"minecraft:green_banner", {0, {0, 0, 0}}}, {"minecraft:green_bed", {0, {0, 0, 0}}}, +{"minecraft:green_candle", {0, {0, 0, 0}}}, +{"minecraft:green_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:green_carpet", {BLOCK_OPAQUE, {84, 109, 27}}}, {"minecraft:green_concrete", {BLOCK_OPAQUE, {73, 91, 36}}}, {"minecraft:green_concrete_powder", {BLOCK_OPAQUE, {97, 119, 44}}}, @@ -305,6 +368,7 @@ {"minecraft:green_wall_banner", {0, {0, 0, 0}}}, {"minecraft:green_wool", {BLOCK_OPAQUE, {84, 109, 27}}}, {"minecraft:grindstone", {BLOCK_OPAQUE, {142, 142, 142}}}, +{"minecraft:hanging_roots", {BLOCK_OPAQUE, {161, 115, 91}}}, {"minecraft:hay_block", {BLOCK_OPAQUE, {165, 139, 12}}}, {"minecraft:heavy_weighted_pressure_plate", {BLOCK_OPAQUE, {220, 220, 220}}}, {"minecraft:honey_block", {BLOCK_OPAQUE, {251, 185, 52}}}, @@ -318,13 +382,14 @@ {"minecraft:infested_chiseled_stone_bricks", {BLOCK_OPAQUE, {119, 118, 119}}}, {"minecraft:infested_cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}}, {"minecraft:infested_cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}}, +{"minecraft:infested_deepslate", {BLOCK_OPAQUE, {80, 80, 82}}}, {"minecraft:infested_mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}}, {"minecraft:infested_stone", {BLOCK_OPAQUE, {125, 125, 125}}}, {"minecraft:infested_stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}}, {"minecraft:iron_bars", {BLOCK_OPAQUE, {136, 139, 135}}}, {"minecraft:iron_block", {BLOCK_OPAQUE, {220, 220, 220}}}, {"minecraft:iron_door", {BLOCK_OPAQUE, {193, 192, 192}}}, -{"minecraft:iron_ore", {BLOCK_OPAQUE, {136, 130, 127}}}, +{"minecraft:iron_ore", {BLOCK_OPAQUE, {136, 129, 122}}}, {"minecraft:iron_trapdoor", {BLOCK_OPAQUE, {202, 202, 202}}}, {"minecraft:item_frame", {0, {0, 0, 0}}}, {"minecraft:jack_o_lantern", {BLOCK_OPAQUE, {214, 152, 52}}}, @@ -350,13 +415,18 @@ {"minecraft:ladder", {0, {0, 0, 0}}}, {"minecraft:lantern", {BLOCK_OPAQUE, {106, 91, 83}}}, {"minecraft:lapis_block", {BLOCK_OPAQUE, {30, 67, 140}}}, -{"minecraft:lapis_ore", {BLOCK_OPAQUE, {99, 110, 132}}}, +{"minecraft:lapis_ore", {BLOCK_OPAQUE, {107, 117, 141}}}, +{"minecraft:large_amethyst_bud", {0, {0, 0, 0}}}, {"minecraft:large_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {125, 125, 125}}}, {"minecraft:lava", {BLOCK_OPAQUE, {212, 90, 18}}}, +{"minecraft:lava_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, {"minecraft:lectern", {BLOCK_OPAQUE, {173, 137, 83}}}, {"minecraft:lever", {0, {0, 0, 0}}}, +{"minecraft:light", {0, {0, 0, 0}}}, {"minecraft:light_blue_banner", {0, {0, 0, 0}}}, {"minecraft:light_blue_bed", {0, {0, 0, 0}}}, +{"minecraft:light_blue_candle", {0, {0, 0, 0}}}, +{"minecraft:light_blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:light_blue_carpet", {BLOCK_OPAQUE, {58, 175, 217}}}, {"minecraft:light_blue_concrete", {BLOCK_OPAQUE, {35, 137, 198}}}, {"minecraft:light_blue_concrete_powder", {BLOCK_OPAQUE, {74, 180, 213}}}, @@ -369,6 +439,8 @@ {"minecraft:light_blue_wool", {BLOCK_OPAQUE, {58, 175, 217}}}, {"minecraft:light_gray_banner", {0, {0, 0, 0}}}, {"minecraft:light_gray_bed", {0, {0, 0, 0}}}, +{"minecraft:light_gray_candle", {0, {0, 0, 0}}}, +{"minecraft:light_gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:light_gray_carpet", {BLOCK_OPAQUE, {142, 142, 134}}}, {"minecraft:light_gray_concrete", {BLOCK_OPAQUE, {125, 125, 115}}}, {"minecraft:light_gray_concrete_powder", {BLOCK_OPAQUE, {154, 154, 148}}}, @@ -380,11 +452,14 @@ {"minecraft:light_gray_wall_banner", {0, {0, 0, 0}}}, {"minecraft:light_gray_wool", {BLOCK_OPAQUE, {142, 142, 134}}}, {"minecraft:light_weighted_pressure_plate", {BLOCK_OPAQUE, {246, 208, 61}}}, +{"minecraft:lightning_rod", {0, {0, 0, 0}}}, {"minecraft:lilac", {BLOCK_OPAQUE, {154, 125, 147}}}, {"minecraft:lily_of_the_valley", {0, {0, 0, 0}}}, {"minecraft:lily_pad", {BLOCK_OPAQUE|BLOCK_GRASS, {133, 133, 133}}}, {"minecraft:lime_banner", {0, {0, 0, 0}}}, {"minecraft:lime_bed", {0, {0, 0, 0}}}, +{"minecraft:lime_candle", {0, {0, 0, 0}}}, +{"minecraft:lime_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:lime_carpet", {BLOCK_OPAQUE, {112, 185, 25}}}, {"minecraft:lime_concrete", {BLOCK_OPAQUE, {94, 168, 24}}}, {"minecraft:lime_concrete_powder", {BLOCK_OPAQUE, {125, 189, 41}}}, @@ -399,6 +474,8 @@ {"minecraft:loom", {BLOCK_OPAQUE, {142, 119, 91}}}, {"minecraft:magenta_banner", {0, {0, 0, 0}}}, {"minecraft:magenta_bed", {0, {0, 0, 0}}}, +{"minecraft:magenta_candle", {0, {0, 0, 0}}}, +{"minecraft:magenta_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:magenta_carpet", {BLOCK_OPAQUE, {189, 68, 179}}}, {"minecraft:magenta_concrete", {BLOCK_OPAQUE, {169, 48, 159}}}, {"minecraft:magenta_concrete_powder", {BLOCK_OPAQUE, {192, 83, 184}}}, @@ -410,8 +487,11 @@ {"minecraft:magenta_wall_banner", {0, {0, 0, 0}}}, {"minecraft:magenta_wool", {BLOCK_OPAQUE, {189, 68, 179}}}, {"minecraft:magma_block", {BLOCK_OPAQUE, {142, 63, 31}}}, +{"minecraft:medium_amethyst_bud", {0, {0, 0, 0}}}, {"minecraft:melon", {BLOCK_OPAQUE, {111, 144, 30}}}, {"minecraft:melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {153, 153, 153}}}, +{"minecraft:moss_block", {BLOCK_OPAQUE, {89, 109, 45}}}, +{"minecraft:moss_carpet", {BLOCK_OPAQUE, {89, 109, 45}}}, {"minecraft:mossy_cobblestone", {BLOCK_OPAQUE, {110, 118, 94}}}, {"minecraft:mossy_cobblestone_slab", {BLOCK_OPAQUE, {110, 118, 94}}}, {"minecraft:mossy_cobblestone_stairs", {BLOCK_OPAQUE, {110, 118, 94}}}, @@ -456,6 +536,8 @@ {"minecraft:obsidian", {BLOCK_OPAQUE, {15, 10, 24}}}, {"minecraft:orange_banner", {0, {0, 0, 0}}}, {"minecraft:orange_bed", {0, {0, 0, 0}}}, +{"minecraft:orange_candle", {0, {0, 0, 0}}}, +{"minecraft:orange_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:orange_carpet", {BLOCK_OPAQUE, {240, 118, 19}}}, {"minecraft:orange_concrete", {BLOCK_OPAQUE, {224, 97, 0}}}, {"minecraft:orange_concrete_powder", {BLOCK_OPAQUE, {227, 131, 31}}}, @@ -468,11 +550,17 @@ {"minecraft:orange_wall_banner", {0, {0, 0, 0}}}, {"minecraft:orange_wool", {BLOCK_OPAQUE, {240, 118, 19}}}, {"minecraft:oxeye_daisy", {0, {0, 0, 0}}}, +{"minecraft:oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}}, +{"minecraft:oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}}, +{"minecraft:oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}}, +{"minecraft:oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}}, {"minecraft:packed_ice", {BLOCK_OPAQUE, {141, 180, 250}}}, {"minecraft:peony", {BLOCK_OPAQUE, {129, 126, 139}}}, {"minecraft:petrified_oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}}, {"minecraft:pink_banner", {0, {0, 0, 0}}}, {"minecraft:pink_bed", {0, {0, 0, 0}}}, +{"minecraft:pink_candle", {0, {0, 0, 0}}}, +{"minecraft:pink_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:pink_carpet", {BLOCK_OPAQUE, {237, 141, 172}}}, {"minecraft:pink_concrete", {BLOCK_OPAQUE, {213, 101, 142}}}, {"minecraft:pink_concrete_powder", {BLOCK_OPAQUE, {228, 153, 181}}}, @@ -489,20 +577,25 @@ {"minecraft:player_head", {0, {0, 0, 0}}}, {"minecraft:player_wall_head", {0, {0, 0, 0}}}, {"minecraft:podzol", {BLOCK_OPAQUE, {91, 63, 24}}}, +{"minecraft:pointed_dripstone", {BLOCK_OPAQUE, {129, 102, 89}}}, {"minecraft:polished_andesite", {BLOCK_OPAQUE, {132, 134, 133}}}, {"minecraft:polished_andesite_slab", {BLOCK_OPAQUE, {132, 134, 133}}}, {"minecraft:polished_andesite_stairs", {BLOCK_OPAQUE, {132, 134, 133}}}, {"minecraft:polished_basalt", {BLOCK_OPAQUE, {99, 98, 100}}}, {"minecraft:polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_blackstone_brick_slab", {BLOCK_OPAQUE, {46, 41, 48}}}, -{"minecraft:polished_blackstone_brick_stairs", {BLOCK_OPAQUE, {46, 41, 48}}}, -{"minecraft:polished_blackstone_brick_wall", {BLOCK_OPAQUE, {46, 41, 48}}}, -{"minecraft:polished_blackstone_bricks", {BLOCK_OPAQUE, {46, 41, 48}}}, +{"minecraft:polished_blackstone_brick_slab", {BLOCK_OPAQUE, {48, 42, 49}}}, +{"minecraft:polished_blackstone_brick_stairs", {BLOCK_OPAQUE, {48, 42, 49}}}, +{"minecraft:polished_blackstone_brick_wall", {BLOCK_OPAQUE, {48, 42, 49}}}, +{"minecraft:polished_blackstone_bricks", {BLOCK_OPAQUE, {48, 42, 49}}}, {"minecraft:polished_blackstone_button", {0, {0, 0, 0}}}, {"minecraft:polished_blackstone_pressure_plate", {BLOCK_OPAQUE, {53, 48, 56}}}, {"minecraft:polished_blackstone_slab", {BLOCK_OPAQUE, {53, 48, 56}}}, {"minecraft:polished_blackstone_stairs", {BLOCK_OPAQUE, {53, 48, 56}}}, {"minecraft:polished_blackstone_wall", {BLOCK_OPAQUE, {53, 48, 56}}}, +{"minecraft:polished_deepslate", {BLOCK_OPAQUE, {72, 72, 73}}}, +{"minecraft:polished_deepslate_slab", {BLOCK_OPAQUE, {72, 72, 73}}}, +{"minecraft:polished_deepslate_stairs", {BLOCK_OPAQUE, {72, 72, 73}}}, +{"minecraft:polished_deepslate_wall", {BLOCK_OPAQUE, {72, 72, 73}}}, {"minecraft:polished_diorite", {BLOCK_OPAQUE, {192, 193, 194}}}, {"minecraft:polished_diorite_slab", {BLOCK_OPAQUE, {192, 193, 194}}}, {"minecraft:polished_diorite_stairs", {BLOCK_OPAQUE, {192, 193, 194}}}, @@ -513,6 +606,7 @@ {"minecraft:potatoes", {BLOCK_OPAQUE, {84, 135, 47}}}, {"minecraft:potted_acacia_sapling", {BLOCK_OPAQUE, {118, 117, 23}}}, {"minecraft:potted_allium", {BLOCK_OPAQUE, {158, 137, 183}}}, +{"minecraft:potted_azalea_bush", {BLOCK_OPAQUE, {101, 124, 47}}}, {"minecraft:potted_azure_bluet", {BLOCK_OPAQUE, {169, 204, 127}}}, {"minecraft:potted_bamboo", {BLOCK_OPAQUE, {93, 144, 19}}}, {"minecraft:potted_birch_sapling", {BLOCK_OPAQUE, {127, 160, 79}}}, @@ -526,6 +620,7 @@ {"minecraft:potted_dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}}, {"minecraft:potted_dead_bush", {BLOCK_OPAQUE, {107, 78, 40}}}, {"minecraft:potted_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {124, 124, 124}}}, +{"minecraft:potted_flowering_azalea_bush", {BLOCK_OPAQUE, {112, 121, 64}}}, {"minecraft:potted_jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}}, {"minecraft:potted_lily_of_the_valley", {BLOCK_OPAQUE, {123, 174, 95}}}, {"minecraft:potted_oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}}, @@ -540,6 +635,8 @@ {"minecraft:potted_warped_roots", {BLOCK_OPAQUE, {20, 136, 123}}}, {"minecraft:potted_white_tulip", {BLOCK_OPAQUE, {93, 164, 71}}}, {"minecraft:potted_wither_rose", {BLOCK_OPAQUE, {41, 44, 23}}}, +{"minecraft:powder_snow", {BLOCK_OPAQUE, {248, 253, 253}}}, +{"minecraft:powder_snow_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, {"minecraft:powered_rail", {BLOCK_OPAQUE, {137, 109, 74}}}, {"minecraft:prismarine", {BLOCK_OPAQUE, {99, 156, 151}}}, {"minecraft:prismarine_brick_slab", {BLOCK_OPAQUE, {99, 171, 158}}}, @@ -552,6 +649,8 @@ {"minecraft:pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {154, 154, 154}}}, {"minecraft:purple_banner", {0, {0, 0, 0}}}, {"minecraft:purple_bed", {0, {0, 0, 0}}}, +{"minecraft:purple_candle", {0, {0, 0, 0}}}, +{"minecraft:purple_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:purple_carpet", {BLOCK_OPAQUE, {121, 42, 172}}}, {"minecraft:purple_concrete", {BLOCK_OPAQUE, {100, 31, 156}}}, {"minecraft:purple_concrete_powder", {BLOCK_OPAQUE, {131, 55, 177}}}, @@ -572,8 +671,13 @@ {"minecraft:quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}}, {"minecraft:quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}}, {"minecraft:rail", {BLOCK_OPAQUE, {125, 111, 88}}}, +{"minecraft:raw_copper_block", {BLOCK_OPAQUE, {154, 105, 79}}}, +{"minecraft:raw_gold_block", {BLOCK_OPAQUE, {221, 169, 46}}}, +{"minecraft:raw_iron_block", {BLOCK_OPAQUE, {166, 135, 107}}}, {"minecraft:red_banner", {0, {0, 0, 0}}}, {"minecraft:red_bed", {0, {0, 0, 0}}}, +{"minecraft:red_candle", {0, {0, 0, 0}}}, +{"minecraft:red_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:red_carpet", {BLOCK_OPAQUE, {160, 39, 34}}}, {"minecraft:red_concrete", {BLOCK_OPAQUE, {142, 32, 32}}}, {"minecraft:red_concrete_powder", {BLOCK_OPAQUE, {168, 54, 50}}}, @@ -598,13 +702,14 @@ {"minecraft:red_wool", {BLOCK_OPAQUE, {160, 39, 34}}}, {"minecraft:redstone_block", {BLOCK_OPAQUE, {175, 24, 5}}}, {"minecraft:redstone_lamp", {BLOCK_OPAQUE, {95, 54, 30}}}, -{"minecraft:redstone_ore", {BLOCK_OPAQUE, {133, 107, 107}}}, +{"minecraft:redstone_ore", {BLOCK_OPAQUE, {140, 109, 109}}}, {"minecraft:redstone_torch", {0, {0, 0, 0}}}, {"minecraft:redstone_wall_torch", {0, {0, 0, 0}}}, {"minecraft:redstone_wire", {BLOCK_OPAQUE, {175, 24, 5}}}, {"minecraft:repeater", {BLOCK_OPAQUE, {160, 157, 156}}}, {"minecraft:repeating_command_block", {BLOCK_OPAQUE, {129, 111, 176}}}, {"minecraft:respawn_anchor", {BLOCK_OPAQUE, {75, 26, 144}}}, +{"minecraft:rooted_dirt", {BLOCK_OPAQUE, {144, 103, 76}}}, {"minecraft:rose_bush", {BLOCK_OPAQUE, {131, 66, 37}}}, {"minecraft:sand", {BLOCK_OPAQUE, {219, 207, 163}}}, {"minecraft:sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, @@ -612,6 +717,7 @@ {"minecraft:sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:sandstone_wall", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:scaffolding", {BLOCK_OPAQUE, {174, 134, 80}}}, +{"minecraft:sculk_sensor", {BLOCK_OPAQUE, {7, 70, 84}}}, {"minecraft:sea_lantern", {BLOCK_OPAQUE, {172, 199, 190}}}, {"minecraft:sea_pickle", {BLOCK_OPAQUE, {90, 97, 39}}}, {"minecraft:seagrass", {0, {0, 0, 0}}}, @@ -621,8 +727,11 @@ {"minecraft:skeleton_skull", {0, {0, 0, 0}}}, {"minecraft:skeleton_wall_skull", {0, {0, 0, 0}}}, {"minecraft:slime_block", {BLOCK_OPAQUE, {111, 192, 91}}}, +{"minecraft:small_amethyst_bud", {0, {0, 0, 0}}}, +{"minecraft:small_dripleaf", {0, {0, 0, 0}}}, {"minecraft:smithing_table", {BLOCK_OPAQUE, {57, 58, 70}}}, -{"minecraft:smoker", {BLOCK_OPAQUE, {84, 82, 80}}}, +{"minecraft:smoker", {BLOCK_OPAQUE, {85, 83, 81}}}, +{"minecraft:smooth_basalt", {BLOCK_OPAQUE, {72, 72, 78}}}, {"minecraft:smooth_quartz", {BLOCK_OPAQUE, {235, 229, 222}}}, {"minecraft:smooth_quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}}, {"minecraft:smooth_quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}}, @@ -645,6 +754,7 @@ {"minecraft:soul_wall_torch", {0, {0, 0, 0}}}, {"minecraft:spawner", {BLOCK_OPAQUE, {36, 46, 62}}}, {"minecraft:sponge", {BLOCK_OPAQUE, {195, 192, 74}}}, +{"minecraft:spore_blossom", {BLOCK_OPAQUE, {206, 96, 158}}}, {"minecraft:spruce_button", {0, {0, 0, 0}}}, {"minecraft:spruce_door", {BLOCK_OPAQUE, {106, 80, 48}}}, {"minecraft:spruce_fence", {BLOCK_OPAQUE, {114, 84, 48}}}, @@ -696,6 +806,7 @@ {"minecraft:tall_seagrass", {BLOCK_OPAQUE, {59, 139, 14}}}, {"minecraft:target", {BLOCK_OPAQUE, {226, 170, 157}}}, {"minecraft:terracotta", {BLOCK_OPAQUE, {152, 94, 67}}}, +{"minecraft:tinted_glass", {BLOCK_OPAQUE, {44, 38, 46}}}, {"minecraft:tnt", {BLOCK_OPAQUE, {142, 62, 53}}}, {"minecraft:torch", {0, {0, 0, 0}}}, {"minecraft:trapped_chest", {BLOCK_OPAQUE, {162, 130, 78}}}, @@ -705,6 +816,7 @@ {"minecraft:tube_coral_block", {BLOCK_OPAQUE, {49, 87, 206}}}, {"minecraft:tube_coral_fan", {0, {0, 0, 0}}}, {"minecraft:tube_coral_wall_fan", {0, {0, 0, 0}}}, +{"minecraft:tuff", {BLOCK_OPAQUE, {108, 109, 102}}}, {"minecraft:turtle_egg", {BLOCK_OPAQUE, {228, 226, 191}}}, {"minecraft:twisting_vines", {BLOCK_OPAQUE, {20, 143, 124}}}, {"minecraft:twisting_vines_plant", {BLOCK_OPAQUE, {20, 135, 122}}}, @@ -730,12 +842,35 @@ {"minecraft:warped_wall_sign", {0, {0, 0, 0}}}, {"minecraft:warped_wart_block", {BLOCK_OPAQUE, {22, 119, 121}}}, {"minecraft:water", {BLOCK_OPAQUE|BLOCK_WATER, {177, 177, 177}}}, +{"minecraft:water_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, +{"minecraft:waxed_copper_block", {BLOCK_OPAQUE, {192, 107, 79}}}, +{"minecraft:waxed_cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}}, +{"minecraft:waxed_cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}}, +{"minecraft:waxed_cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}}, +{"minecraft:waxed_exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}}, +{"minecraft:waxed_exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}}, +{"minecraft:waxed_exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}}, +{"minecraft:waxed_exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}}, +{"minecraft:waxed_oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}}, +{"minecraft:waxed_oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}}, +{"minecraft:waxed_oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}}, +{"minecraft:waxed_oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}}, +{"minecraft:waxed_weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}}, +{"minecraft:waxed_weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}}, +{"minecraft:waxed_weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}}, +{"minecraft:waxed_weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}}, +{"minecraft:weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}}, +{"minecraft:weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}}, +{"minecraft:weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}}, +{"minecraft:weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}}, {"minecraft:weeping_vines", {BLOCK_OPAQUE, {104, 1, 0}}}, {"minecraft:weeping_vines_plant", {BLOCK_OPAQUE, {132, 16, 12}}}, {"minecraft:wet_sponge", {BLOCK_OPAQUE, {171, 181, 70}}}, {"minecraft:wheat", {BLOCK_OPAQUE, {166, 151, 73}}}, {"minecraft:white_banner", {0, {0, 0, 0}}}, {"minecraft:white_bed", {0, {0, 0, 0}}}, +{"minecraft:white_candle", {0, {0, 0, 0}}}, +{"minecraft:white_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:white_carpet", {BLOCK_OPAQUE, {233, 236, 236}}}, {"minecraft:white_concrete", {BLOCK_OPAQUE, {207, 213, 214}}}, {"minecraft:white_concrete_powder", {BLOCK_OPAQUE, {225, 227, 227}}}, @@ -752,6 +887,8 @@ {"minecraft:wither_skeleton_wall_skull", {0, {0, 0, 0}}}, {"minecraft:yellow_banner", {0, {0, 0, 0}}}, {"minecraft:yellow_bed", {0, {0, 0, 0}}}, +{"minecraft:yellow_candle", {0, {0, 0, 0}}}, +{"minecraft:yellow_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, {"minecraft:yellow_carpet", {BLOCK_OPAQUE, {248, 197, 39}}}, {"minecraft:yellow_concrete", {BLOCK_OPAQUE, {240, 175, 21}}}, {"minecraft:yellow_concrete_powder", {BLOCK_OPAQUE, {232, 199, 54}}}, From af1afc33155369e311726bff00014c013d11af64 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 24 Jun 2021 00:12:27 +0200 Subject: [PATCH 011/460] Biome: add Dripstone Caves and Lush Caves Temperature and downfall values were taken from the Caves & Cliffs: Part II Preview datapack. --- src/Resource/Biome.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index 440b1d4..65f4831 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -342,6 +342,8 @@ const Biome *const BIOMES[256] = { /* 171 */ &BiomeDesert, /* Crimson Forest */ /* 172 */ &BiomeDesert, /* Warped Forest */ /* 173 */ &BiomeDesert, /* Basalt Deltas */ + /* 174 */ &BiomePlains, /* Dripstone Caves */ + /* 175 */ &BiomeDefault, /* Lush Caves */ }; } From 73e5c12cdee73a15d3e005791bd833a1e6488065 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 25 Jun 2021 19:43:14 +0200 Subject: [PATCH 012/460] Rename .inc files to .inc.cpp for better language detection by editors and Github --- resource/README.md | 4 ++-- resource/generate.py | 2 +- src/Resource/BlockType.cpp | 4 ++-- src/Resource/{BlockType.inc => BlockType.inc.cpp} | 0 src/Resource/{LegacyBlockType.inc => LegacyBlockType.inc.cpp} | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename src/Resource/{BlockType.inc => BlockType.inc.cpp} (100%) rename src/Resource/{LegacyBlockType.inc => LegacyBlockType.inc.cpp} (100%) diff --git a/resource/README.md b/resource/README.md index ed35118..f9dc955 100644 --- a/resource/README.md +++ b/resource/README.md @@ -10,7 +10,7 @@ work. of two different versions - `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 `BlockType.inc` from `colors.json` +- `generate.py`: Generates `BlockType.inc.cpp` from `colors.json` In addition to these scripts, the JSON processor *jq* is a useful tool to work with MinedMap's resource metadata. @@ -63,7 +63,7 @@ with MinedMap's resource metadata. 7. Update the source code with the new block colors: ```sh - ./generate.py colors.json ../src/Resource/BlockType.inc + ./generate.py colors.json ../src/Resource/BlockType.inc.cpp ``` After the update, the new version should be tested with old savegames (both diff --git a/resource/generate.py b/resource/generate.py index 8508c6b..de1f828 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -6,7 +6,7 @@ import sys if len(sys.argv) != 3: - sys.exit('Usage: extract.py ') + sys.exit('Usage: extract.py ') with open(sys.argv[1]) as f: colors = json.load(f) diff --git a/src/Resource/BlockType.cpp b/src/Resource/BlockType.cpp index e72456e..8e04c58 100644 --- a/src/Resource/BlockType.cpp +++ b/src/Resource/BlockType.cpp @@ -32,7 +32,7 @@ namespace Resource { const std::unordered_map BlockType::Types = { -#include "BlockType.inc" +#include "BlockType.inc.cpp" }; @@ -51,7 +51,7 @@ static constexpr LegacyBlockType simple(const char *t) { static const LegacyBlockType LEGACY_BLOCK_TYPE_DATA[256] = { -#include "LegacyBlockType.inc" +#include "LegacyBlockType.inc.cpp" }; diff --git a/src/Resource/BlockType.inc b/src/Resource/BlockType.inc.cpp similarity index 100% rename from src/Resource/BlockType.inc rename to src/Resource/BlockType.inc.cpp diff --git a/src/Resource/LegacyBlockType.inc b/src/Resource/LegacyBlockType.inc.cpp similarity index 100% rename from src/Resource/LegacyBlockType.inc rename to src/Resource/LegacyBlockType.inc.cpp From 5263538a29c9c6030ced078a509dff48f9c4451f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 26 Jun 2021 16:43:06 +0200 Subject: [PATCH 013/460] README.md: add 1.17 support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2c2daa..2fb8452 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.16 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.17 (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 * Incremental updates: only recreate map tiles for regions that have changed From fdce587c74228f80b214121515baa2540d836f53 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 24 Aug 2021 13:07:31 +0200 Subject: [PATCH 014/460] build: update to modern CMake, use pkg-config for zlib and libpng Starting with CMake 3.7, we can avoid dealing with individual variables for include dirs, libraries, ... for dependencies found using pkg-config, and instead just reference them using an imported target. --- CMakeLists.txt | 8 ++++---- src/CMakeLists.txt | 12 ++++-------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 362fa58..70385e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.7) project(MINEDMAP CXX) +find_package(PkgConfig REQUIRED) -find_package(PNG REQUIRED) -find_package(ZLIB REQUIRED) - +pkg_check_modules(ZLIB REQUIRED IMPORTED_TARGET zlib) +pkg_check_modules(PNG REQUIRED IMPORTED_TARGET libpng16) add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1eea2b3..0e4fd48 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,4 @@ -include_directories(${ZLIB_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}) -add_definitions(${PNG_DEFINITIONS}) +add_compile_options(-std=c++11 -Wall) add_executable(MinedMap MinedMap.cpp @@ -16,16 +15,14 @@ add_executable(MinedMap World/Region.cpp World/Section.cpp ) -set_target_properties(MinedMap PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall") -target_link_libraries(MinedMap ${ZLIB_LIBRARIES} ${PNG_LIBRARIES}) +target_link_libraries(MinedMap PkgConfig::ZLIB PkgConfig::PNG) add_executable(nbtdump nbtdump.cpp GZip.cpp NBT/Tag.cpp ) -set_target_properties(nbtdump PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall") -target_link_libraries(nbtdump ${ZLIB_LIBRARIES}) +target_link_libraries(nbtdump PkgConfig::ZLIB) add_executable(regiondump regiondump.cpp @@ -34,7 +31,6 @@ add_executable(regiondump World/ChunkData.cpp World/Region.cpp ) -set_target_properties(regiondump PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall") -target_link_libraries(regiondump ${ZLIB_LIBRARIES}) +target_link_libraries(regiondump PkgConfig::ZLIB) install(TARGETS MinedMap RUNTIME DESTINATION bin) From 38d8bd07386cb415cbe23d2fe56ed8be38cf4c53 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 24 Aug 2021 21:03:18 +0200 Subject: [PATCH 015/460] Chunk: replace withDepth argument with extensible flags field --- src/MinedMap.cpp | 4 ++-- src/World/Chunk.cpp | 10 +++++----- src/World/Chunk.hpp | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index 4855b6f..a361ab0 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -56,7 +56,7 @@ static const size_t DIM = World::Region::SIZE*World::Chunk::SIZE; static void addChunkBiome(uint8_t biomemap[DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) { World::Chunk chunk(data); - World::Chunk::Heightmap layer = chunk.getTopLayer(false); + World::Chunk::Heightmap layer = chunk.getTopLayer(0); for (size_t x = 0; x < World::Chunk::SIZE; x++) { for (size_t z = 0; z < World::Chunk::SIZE; z++) { @@ -127,7 +127,7 @@ static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM] const World::ChunkData *data, const std::unique_ptr biomemaps[3][3] ) { World::Chunk chunk(data); - World::Chunk::Heightmap layer = chunk.getTopLayer(true); + World::Chunk::Heightmap layer = chunk.getTopLayer(World::Chunk::WITH_DEPTH); for (size_t x = 0; x < World::Chunk::SIZE; x++) { for (size_t z = 0; z < World::Chunk::SIZE; z++) { diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 423d7e8..e428892 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -101,11 +101,11 @@ Block Chunk::getBlock(size_t x, Chunk::Height height, size_t z) const { return block; } -bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, size_t y, size_t z, bool withDepth) const { +bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, size_t y, size_t z, int flags) const { if (height->depth > 0) return false; - if (!withDepth && height->y > 0) + if (!(flags & WITH_DEPTH) && height->y > 0) return false; const Resource::BlockType *type = section->getBlockStateAt(x, y, z); @@ -115,7 +115,7 @@ bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, s if (height->y == 0) height->y = SIZE*section->getY() + y; - if (!withDepth) + if (!(flags & WITH_DEPTH)) return true; if (type->flags & BLOCK_WATER) @@ -126,7 +126,7 @@ bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, s return true; } -Chunk::Heightmap Chunk::getTopLayer(bool withDepth) const { +Chunk::Heightmap Chunk::getTopLayer(int flags) const { size_t done = 0; Heightmap ret = {}; @@ -145,7 +145,7 @@ Chunk::Heightmap Chunk::getTopLayer(bool withDepth) const { for (size_t z = 0; z < SIZE; z++) { for (size_t x = 0; x < SIZE; x++) { - if (getHeight(&ret.v[x][z], section, x, y, z, withDepth)) + if (getHeight(&ret.v[x][z], section, x, y, z, flags)) done++; } } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index ccbba54..bcffa1e 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -50,6 +50,9 @@ public: static const size_t BSIZE = SIZE / BGROUP; static const size_t BMAXY = MAXY / BGROUP; + // Flags + static const int WITH_DEPTH = (1 << 0); + struct Height { unsigned y; unsigned depth; @@ -67,7 +70,7 @@ private: std::shared_ptr biomeIntsPre115; std::shared_ptr biomeInts; - bool getHeight(Height *height, const Section *section, size_t x, size_t y, size_t z, bool withDepth) const; + bool getHeight(Height *height, const Section *section, size_t x, size_t y, size_t z, int flags) const; const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const { size_t Y = y / SIZE; @@ -89,7 +92,7 @@ public: uint8_t getBiome(size_t x, size_t y, size_t z) const; Block getBlock(size_t x, Height y, size_t z) const; - Heightmap getTopLayer(bool withDepth) const; + Heightmap getTopLayer(int flags) const; }; } From fd4773c8cac7fc3e86983211ef9676f5162b593b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 17 Nov 2021 12:07:56 +0100 Subject: [PATCH 016/460] treewide: replace license headers with SPDX-License-Identifier --- src/Buffer.hpp | 21 +-------------------- src/GZip.cpp | 21 +-------------------- src/GZip.hpp | 21 +-------------------- src/Info.cpp | 21 +-------------------- src/Info.hpp | 21 +-------------------- src/MinedMap.cpp | 21 +-------------------- src/NBT/ByteArrayTag.hpp | 21 +-------------------- src/NBT/ByteTag.hpp | 21 +-------------------- src/NBT/CompoundTag.hpp | 21 +-------------------- src/NBT/DoubleTag.hpp | 21 +-------------------- src/NBT/EndTag.hpp | 21 +-------------------- src/NBT/FloatTag.hpp | 21 +-------------------- src/NBT/IntArrayTag.hpp | 21 +-------------------- src/NBT/IntTag.hpp | 21 +-------------------- src/NBT/ListTag.hpp | 21 +-------------------- src/NBT/LongArrayTag.hpp | 21 +-------------------- src/NBT/LongTag.hpp | 21 +-------------------- src/NBT/ShortTag.hpp | 21 +-------------------- src/NBT/StringTag.hpp | 21 +-------------------- src/NBT/Tag.cpp | 21 +-------------------- src/NBT/Tag.hpp | 21 +-------------------- src/PNG.cpp | 21 +-------------------- src/PNG.hpp | 21 +-------------------- src/Resource/Biome.cpp | 21 +-------------------- src/Resource/Biome.hpp | 21 +-------------------- src/Resource/BlockType.cpp | 21 +-------------------- src/Resource/BlockType.hpp | 21 +-------------------- src/Resource/Color.hpp | 21 +-------------------- src/UniqueCPtr.hpp | 21 +-------------------- src/Util.hpp | 21 +-------------------- src/World/Block.hpp | 21 +-------------------- src/World/Chunk.cpp | 21 +-------------------- src/World/Chunk.hpp | 21 +-------------------- src/World/ChunkData.cpp | 21 +-------------------- src/World/ChunkData.hpp | 21 +-------------------- src/World/Level.cpp | 21 +-------------------- src/World/Level.hpp | 21 +-------------------- src/World/Region.cpp | 21 +-------------------- src/World/Region.hpp | 21 +-------------------- src/World/Section.cpp | 21 +-------------------- src/World/Section.hpp | 21 +-------------------- src/nbtdump.cpp | 21 +-------------------- src/regiondump.cpp | 23 ++--------------------- 43 files changed, 44 insertions(+), 861 deletions(-) diff --git a/src/Buffer.hpp b/src/Buffer.hpp index 9975dcb..89d4649 100644 --- a/src/Buffer.hpp +++ b/src/Buffer.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/GZip.cpp b/src/GZip.cpp index 0005923..28f4737 100644 --- a/src/GZip.cpp +++ b/src/GZip.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/GZip.hpp b/src/GZip.hpp index 8505039..8449758 100644 --- a/src/GZip.hpp +++ b/src/GZip.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Info.cpp b/src/Info.cpp index 9d9d751..48bbb45 100644 --- a/src/Info.cpp +++ b/src/Info.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Info.hpp b/src/Info.hpp index 24f0c0e..4ab7dd3 100644 --- a/src/Info.hpp +++ b/src/Info.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index a361ab0..5318f33 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/ByteArrayTag.hpp b/src/NBT/ByteArrayTag.hpp index 95e9ddb..9c73647 100644 --- a/src/NBT/ByteArrayTag.hpp +++ b/src/NBT/ByteArrayTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/ByteTag.hpp b/src/NBT/ByteTag.hpp index c578b9c..7d3fff5 100644 --- a/src/NBT/ByteTag.hpp +++ b/src/NBT/ByteTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/CompoundTag.hpp b/src/NBT/CompoundTag.hpp index 2d3fcbe..b1e7521 100644 --- a/src/NBT/CompoundTag.hpp +++ b/src/NBT/CompoundTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/DoubleTag.hpp b/src/NBT/DoubleTag.hpp index b83efe2..a28c38a 100644 --- a/src/NBT/DoubleTag.hpp +++ b/src/NBT/DoubleTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/EndTag.hpp b/src/NBT/EndTag.hpp index 167412a..859d77a 100644 --- a/src/NBT/EndTag.hpp +++ b/src/NBT/EndTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/FloatTag.hpp b/src/NBT/FloatTag.hpp index 8748bc6..637c74b 100644 --- a/src/NBT/FloatTag.hpp +++ b/src/NBT/FloatTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/IntArrayTag.hpp b/src/NBT/IntArrayTag.hpp index 4dfcd05..cc24665 100644 --- a/src/NBT/IntArrayTag.hpp +++ b/src/NBT/IntArrayTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/IntTag.hpp b/src/NBT/IntTag.hpp index e6babd0..b2c2660 100644 --- a/src/NBT/IntTag.hpp +++ b/src/NBT/IntTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp index 7276923..6582098 100644 --- a/src/NBT/ListTag.hpp +++ b/src/NBT/ListTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/LongArrayTag.hpp b/src/NBT/LongArrayTag.hpp index 2e24d5a..2e54762 100644 --- a/src/NBT/LongArrayTag.hpp +++ b/src/NBT/LongArrayTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/LongTag.hpp b/src/NBT/LongTag.hpp index 05f6bc2..450f6b4 100644 --- a/src/NBT/LongTag.hpp +++ b/src/NBT/LongTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/ShortTag.hpp b/src/NBT/ShortTag.hpp index 593a1ed..32f32a2 100644 --- a/src/NBT/ShortTag.hpp +++ b/src/NBT/ShortTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/StringTag.hpp b/src/NBT/StringTag.hpp index 6fb2b41..40c5bfb 100644 --- a/src/NBT/StringTag.hpp +++ b/src/NBT/StringTag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/Tag.cpp b/src/NBT/Tag.cpp index e8c429f..57dd395 100644 --- a/src/NBT/Tag.cpp +++ b/src/NBT/Tag.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/NBT/Tag.hpp b/src/NBT/Tag.hpp index 3fb824b..98c0ae2 100644 --- a/src/NBT/Tag.hpp +++ b/src/NBT/Tag.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/PNG.cpp b/src/PNG.cpp index 4e12608..5c2c098 100644 --- a/src/PNG.cpp +++ b/src/PNG.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/PNG.hpp b/src/PNG.hpp index b1a66dd..fdd2dc0 100644 --- a/src/PNG.hpp +++ b/src/PNG.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index 65f4831..8384456 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -1,27 +1,8 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, 2018, Matthias Schiffer Copyright (c) 2019, Roman Shishkin All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Resource/Biome.hpp b/src/Resource/Biome.hpp index e094f17..5583e08 100644 --- a/src/Resource/Biome.hpp +++ b/src/Resource/Biome.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Resource/BlockType.cpp b/src/Resource/BlockType.cpp index 8e04c58..cc76cff 100644 --- a/src/Resource/BlockType.cpp +++ b/src/Resource/BlockType.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Resource/BlockType.hpp b/src/Resource/BlockType.hpp index a551830..6861448 100644 --- a/src/Resource/BlockType.hpp +++ b/src/Resource/BlockType.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Resource/Color.hpp b/src/Resource/Color.hpp index bad2df6..255db1b 100644 --- a/src/Resource/Color.hpp +++ b/src/Resource/Color.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/UniqueCPtr.hpp b/src/UniqueCPtr.hpp index 9e70b89..647f7e1 100644 --- a/src/UniqueCPtr.hpp +++ b/src/UniqueCPtr.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/Util.hpp b/src/Util.hpp index 68a83b1..e76fd6d 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Block.hpp b/src/World/Block.hpp index 30ed186..75a949d 100644 --- a/src/World/Block.hpp +++ b/src/World/Block.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index e428892..4d77c10 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2019, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index bcffa1e..57fe314 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/ChunkData.cpp b/src/World/ChunkData.cpp index 6cb73b5..972ee5e 100644 --- a/src/World/ChunkData.cpp +++ b/src/World/ChunkData.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/ChunkData.hpp b/src/World/ChunkData.hpp index 5fe27c9..cb27f7b 100644 --- a/src/World/ChunkData.hpp +++ b/src/World/ChunkData.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Level.cpp b/src/World/Level.cpp index 56628b9..ec7d25a 100644 --- a/src/World/Level.cpp +++ b/src/World/Level.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Level.hpp b/src/World/Level.hpp index 6fd45a8..dd40513 100644 --- a/src/World/Level.hpp +++ b/src/World/Level.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Region.cpp b/src/World/Region.cpp index a813247..65ee913 100644 --- a/src/World/Region.cpp +++ b/src/World/Region.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Region.hpp b/src/World/Region.hpp index 00bfd7b..7681bbc 100644 --- a/src/World/Region.hpp +++ b/src/World/Region.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Section.cpp b/src/World/Section.cpp index 23b0ebf..dbf633f 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2019, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/World/Section.hpp b/src/World/Section.hpp index 7e90acb..0791c26 100644 --- a/src/World/Section.hpp +++ b/src/World/Section.hpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2015-2019, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/nbtdump.cpp b/src/nbtdump.cpp index b364f41..d47b15e 100644 --- a/src/nbtdump.cpp +++ b/src/nbtdump.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ diff --git a/src/regiondump.cpp b/src/regiondump.cpp index 52ea31c..8e3deb4 100644 --- a/src/regiondump.cpp +++ b/src/regiondump.cpp @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2018, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -48,4 +29,4 @@ int main(int argc, char *argv[]) { }); return 0; -} \ No newline at end of file +} From d4be401bcdb92b9a8a1a4878f62e0511515fdc65 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Dec 2021 22:28:22 +0100 Subject: [PATCH 017/460] Resource: Biome: fix integer underflow Explicitly cast height value to signed integer to fix incorrect biome color values below a height of 64. --- src/Resource/Biome.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index 8384456..c9e928b 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -49,7 +49,7 @@ FloatColor Biome::getBlockColor(const BlockType *type, unsigned height) const { float(type->color.b), }; - float t = clamp(temp - std::max(0.0f, (height-64)/600.0f), 0, 1); + float t = clamp(temp - std::max(0.0f, (int(height)-64)/600.0f), 0, 1); float r = clamp(rain, 0, 1) * t; if (type->flags & BLOCK_GRASS) From 457e993c92327d1c5ba81b653ee4e819ecc48902 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 17 Nov 2021 12:25:26 +0100 Subject: [PATCH 018/460] Introduce separate types for block/section/chunk indices Newtypes are cumbersome in C++, so this is mostly documentation for now. Also replace lots of questionable uses of size_t with int or types with explicit width and add a few comments for constants. --- LICENSE | 2 +- src/MinedMap.cpp | 51 ++++++++++++++++++++++-------------------- src/Resource/Biome.cpp | 5 ++--- src/Resource/Biome.hpp | 5 +++-- src/Util.hpp | 15 ++++++++++++- src/World/Block.hpp | 4 ++-- src/World/Chunk.cpp | 31 +++++++++++++------------ src/World/Chunk.hpp | 35 ++++++++++++++++++----------- src/World/Region.cpp | 15 +++++++------ src/World/Region.hpp | 11 ++++----- src/World/Section.cpp | 11 +++++---- src/World/Section.hpp | 26 +++++++++++---------- src/regiondump.cpp | 4 ++-- 13 files changed, 123 insertions(+), 92 deletions(-) diff --git a/LICENSE b/LICENSE index 0372923..e243464 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2019, Matthias Schiffer +Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index 5318f33..6c55851 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -32,15 +32,15 @@ namespace MinedMap { static const int BIOME_SMOOTH = 3; -static const size_t DIM = World::Region::SIZE*World::Chunk::SIZE; +static const uint32_t DIM = World::Region::SIZE*World::Chunk::SIZE; -static void addChunkBiome(uint8_t biomemap[DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) { +static void addChunkBiome(uint8_t biomemap[DIM*DIM], chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *data) { World::Chunk chunk(data); World::Chunk::Heightmap layer = chunk.getTopLayer(0); - for (size_t x = 0; x < World::Chunk::SIZE; x++) { - for (size_t z = 0; z < World::Chunk::SIZE; z++) { + for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) { + for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) { size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; const World::Chunk::Height &height = layer.v[x][z]; biomemap[i] = chunk.getBiome(x, height.y, z); @@ -48,20 +48,20 @@ static void addChunkBiome(uint8_t biomemap[DIM*DIM], size_t X, size_t Z, const W } } -static uint8_t biomeAt(ssize_t x, ssize_t z, const std::unique_ptr biomemaps[3][3]) { +static uint8_t biomeAt(int16_t x, int16_t z, const std::unique_ptr biomemaps[3][3]) { size_t a = 1, b = 1; if (x < 0) { a--; x += DIM; - } else if (x >= (ssize_t)DIM) { + } else if (x >= (int32_t)DIM) { a++; x -= DIM; } if (z < 0) { b--; z += DIM; - } else if (z >= (ssize_t)DIM) { + } else if (z >= (int32_t)DIM) { b++; z -= DIM; } @@ -69,10 +69,13 @@ static uint8_t biomeAt(ssize_t x, ssize_t z, const std::unique_ptr bi return biomemaps[a][b].get()[z*DIM + x]; } -static Resource::Color collectColors(size_t x, size_t z, const World::Block &block, const std::unique_ptr biomemaps[3][3]) { - std::unordered_map biomes; - for (int dx = -BIOME_SMOOTH; dx <= BIOME_SMOOTH; dx++) { - for (int dz = -BIOME_SMOOTH; dz <= BIOME_SMOOTH; dz++) { +static Resource::Color collectColors( + region_block_idx_t x, region_block_idx_t z, + const World::Block &block, const std::unique_ptr biomemaps[3][3] +) { + std::unordered_map biomes; + for (int16_t dx = -BIOME_SMOOTH; dx <= BIOME_SMOOTH; dx++) { + for (int16_t dz = -BIOME_SMOOTH; dz <= BIOME_SMOOTH; dz++) { if (std::abs(dx) + std::abs(dz) > BIOME_SMOOTH) continue; @@ -85,11 +88,11 @@ static Resource::Color collectColors(size_t x, size_t z, const World::Block &blo } Resource::FloatColor c = {}; - size_t total = 0; + unsigned total = 0; for (const auto &e : biomes) { uint8_t biome = e.first; - size_t count = e.second; + unsigned count = e.second; if (biome == 0xff) continue; @@ -104,14 +107,14 @@ static Resource::Color collectColors(size_t x, size_t z, const World::Block &blo return (1.0f / total) * c; } -static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], size_t X, size_t Z, +static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *data, const std::unique_ptr biomemaps[3][3] ) { World::Chunk chunk(data); World::Chunk::Heightmap layer = chunk.getTopLayer(World::Chunk::WITH_DEPTH); - for (size_t x = 0; x < World::Chunk::SIZE; x++) { - for (size_t z = 0; z < World::Chunk::SIZE; z++) { + for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) { + for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) { size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; const World::Chunk::Height &height = layer.v[x][z]; World::Block block = chunk.getBlock(x, height, z); @@ -261,7 +264,7 @@ static void makeBiome(const std::string ®iondir, const std::string &outputdir std::unique_ptr biomemap(new uint8_t[DIM*DIM]); std::memset(biomemap.get(), 0xff, DIM*DIM); - World::Region::visitChunks(input.c_str(), [&] (size_t X, size_t Z, const World::ChunkData *chunk) { + World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { addChunkBiome(biomemap.get(), X, Z, chunk); }); @@ -289,8 +292,8 @@ static void makeMap(const std::string ®iondir, const std::string &outputdir, if (intime == INT64_MIN) return; - for (size_t i = 0; i < 3; i++) { - for (size_t j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { biomenames[i][j] = outputdir + "/biome/" + formatTileName(x + i - 1, z + j - 1, "png"); intime = std::max(intime, getModTime(biomenames[i][j])); } @@ -304,8 +307,8 @@ static void makeMap(const std::string ®iondir, const std::string &outputdir, try { std::unique_ptr biomemaps[3][3]; - for (size_t i = 0; i < 3; i++) { - for (size_t j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { biomemaps[i][j].reset(new uint8_t[DIM*DIM]); std::memset(biomemaps[i][j].get(), 0, DIM*DIM); @@ -320,7 +323,7 @@ static void makeMap(const std::string ®iondir, const std::string &outputdir, std::unique_ptr lightmap(new uint8_t[2*DIM*DIM]); std::memset(lightmap.get(), 0, 2*DIM*DIM); - World::Region::visitChunks(input.c_str(), [&] (size_t X, size_t Z, const World::ChunkData *chunk) { + World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { addChunk(image.get(), lightmap.get(), X, Z, chunk, biomemaps); }); @@ -355,7 +358,7 @@ static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG:: const char *se = se_str.c_str(); int64_t t = INT64_MIN; - size_t count = 0; + unsigned count = 0; for (auto name : {&nw, &ne, &sw, &se}) { struct stat s; if (stat(*name, &s) < 0) { diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index c9e928b..3cf1586 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, 2018, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer Copyright (c) 2019, Roman Shishkin All rights reserved. */ @@ -9,7 +9,6 @@ #include "Biome.hpp" #include "BlockType.hpp" -#include "../Util.hpp" namespace MinedMap { @@ -42,7 +41,7 @@ FloatColor Biome::getFoliageColor(float temp, float rain) const { } -FloatColor Biome::getBlockColor(const BlockType *type, unsigned height) const { +FloatColor Biome::getBlockColor(const BlockType *type, y_idx_t height) const { FloatColor c = { float(type->color.r), float(type->color.g), diff --git a/src/Resource/Biome.hpp b/src/Resource/Biome.hpp index 5583e08..490668c 100644 --- a/src/Resource/Biome.hpp +++ b/src/Resource/Biome.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -8,6 +8,7 @@ #pragma once #include "Color.hpp" +#include "../Util.hpp" namespace MinedMap { @@ -30,7 +31,7 @@ public: Biome(float temp0, float rain0, FloatColor water0 = {0.247f, 0.463f, 0.894f}) : temp(temp0), rain(rain0), water(water0) {} - FloatColor getBlockColor(const BlockType *type, unsigned height) const; + FloatColor getBlockColor(const BlockType *type, y_idx_t height) const; }; extern const Biome *const BIOME_DEFAULT; diff --git a/src/Util.hpp b/src/Util.hpp index e76fd6d..1f50958 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -25,4 +26,16 @@ static inline float clamp(float v, float min, float max) { return std::max(std::min(v, max), min); } +// A block coordinate relative to a chunk/section (X/Y/Z) +typedef uint8_t block_idx_t; +// A section index in a chunk (Y) +typedef uint8_t section_idx_t; +// A chunk coordinate relative to a region (X/Z) +typedef uint8_t chunk_idx_t; + +// A block coordinate relative to a region (X/Z) +typedef uint16_t region_block_idx_t; +// A block coordinate (Y) +typedef uint16_t y_idx_t; + } diff --git a/src/World/Block.hpp b/src/World/Block.hpp index 75a949d..2f207a3 100644 --- a/src/World/Block.hpp +++ b/src/World/Block.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -17,7 +17,7 @@ namespace World { struct Block { const Resource::BlockType *type; - unsigned depth; + y_idx_t depth; uint8_t blockLight; bool isVisible() const { diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 4d77c10..e99af79 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015-2019, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -42,13 +42,13 @@ Chunk::Chunk(const ChunkData *data) { for (auto &sTag : *sectionsTag) { auto s = std::dynamic_pointer_cast(sTag); std::unique_ptr
section = Section::makeSection(s, dataVersion); - size_t Y = section->getY(); + section_idx_t Y = section->getY(); sections.resize(Y); sections.push_back(std::move(section)); } } -uint8_t Chunk::getBiome(size_t x, size_t y, size_t z) const { +uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { if (x > SIZE || y > MAXY || z > SIZE) throw std::invalid_argument("corrupt chunk data"); @@ -62,19 +62,19 @@ uint8_t Chunk::getBiome(size_t x, size_t y, size_t z) const { return 0xff; } -Block Chunk::getBlock(size_t x, Chunk::Height height, size_t z) const { +Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const { Block block = {}; block.depth = height.depth; - size_t Y = height.y / SIZE; - size_t y = height.y % SIZE; + section_idx_t Y = height.y / SIZE; + block_idx_t y = height.y % SIZE; if (Y < sections.size() && sections[Y]) block.type = sections[Y]->getBlockStateAt(x, y, z); - size_t Yt = (height.y + 1) / SIZE; - size_t yt = (height.y + 1) % SIZE; + section_idx_t Yt = (height.y + 1) / SIZE; + block_idx_t yt = (height.y + 1) % SIZE; if (Yt < sections.size() && sections[Yt]) block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); @@ -82,7 +82,10 @@ Block Chunk::getBlock(size_t x, Chunk::Height height, size_t z) const { return block; } -bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, size_t y, size_t z, int flags) const { +bool Chunk::getHeight( + Chunk::Height *height, const Section *section, + block_idx_t x, block_idx_t y, block_idx_t z, int flags +) const { if (height->depth > 0) return false; @@ -108,10 +111,10 @@ bool Chunk::getHeight(Chunk::Height *height, const Section *section, size_t x, s } Chunk::Heightmap Chunk::getTopLayer(int flags) const { - size_t done = 0; + uint32_t done = 0; Heightmap ret = {}; - for (ssize_t Y = sections.size() - 1; Y >= 0; Y--) { + for (int16_t Y = sections.size() - 1; Y >= 0; Y--) { if (done == SIZE*SIZE) break; @@ -120,12 +123,12 @@ Chunk::Heightmap Chunk::getTopLayer(int flags) const { const Section *section = sections[Y].get(); - for (ssize_t y = SIZE-1; y >= 0; y--) { + for (int8_t y = SIZE-1; y >= 0; y--) { if (done == SIZE*SIZE) break; - for (size_t z = 0; z < SIZE; z++) { - for (size_t x = 0; x < SIZE; x++) { + for (block_idx_t z = 0; z < SIZE; z++) { + for (block_idx_t x = 0; x < SIZE; x++) { if (getHeight(&ret.v[x][z], section, x, y, z, flags)) done++; } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 57fe314..26d10d1 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015-2018, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -24,19 +24,25 @@ namespace World { class Chunk { public: - static const size_t SIZE = Section::SIZE; - static const size_t MAXY = 256; + // Number of blocks in a chunk in x/z dimensions + static const uint32_t SIZE = Section::SIZE; + // Maximum Y value + static const y_idx_t MAXY = 256; - static const size_t BGROUP = 4; - static const size_t BSIZE = SIZE / BGROUP; - static const size_t BMAXY = MAXY / BGROUP; + // Since Minecraft 1.15, biome information is stored for + // 4x4x4 block groups + static const uint32_t BGROUP = 4; + // Number of biome values in a chunk in x/z dimensions + static const uint32_t BSIZE = SIZE / BGROUP; + // Number of biome values in a chunk in y dimension + static const uint32_t BMAXY = MAXY / BGROUP; // Flags static const int WITH_DEPTH = (1 << 0); struct Height { - unsigned y; - unsigned depth; + y_idx_t y; + y_idx_t depth; }; struct Heightmap { @@ -51,10 +57,13 @@ private: std::shared_ptr biomeIntsPre115; std::shared_ptr biomeInts; - bool getHeight(Height *height, const Section *section, size_t x, size_t y, size_t z, int flags) const; + bool getHeight( + Height *height, const Section *section, + block_idx_t x, block_idx_t y, block_idx_t z, int flags + ) const; - const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const { - size_t Y = y / SIZE; + const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const { + section_idx_t Y = y / SIZE; if (Y >= sections.size() || !sections[Y]) return nullptr; @@ -70,8 +79,8 @@ public: return *level; } - uint8_t getBiome(size_t x, size_t y, size_t z) const; - Block getBlock(size_t x, Height y, size_t z) const; + uint8_t getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const; + Block getBlock(block_idx_t x, Height y, block_idx_t z) const; Heightmap getTopLayer(int flags) const; }; diff --git a/src/World/Region.cpp b/src/World/Region.cpp index 65ee913..cd21e6d 100644 --- a/src/World/Region.cpp +++ b/src/World/Region.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -18,16 +18,16 @@ namespace World { Region::ChunkMap Region::processHeader(const uint8_t header[4096]) { ChunkMap map; - for (size_t z = 0; z < 32; z++) { - for (size_t x = 0; x < 32; x++) { + for (chunk_idx_t z = 0; z < 32; z++) { + for (chunk_idx_t x = 0; x < 32; x++) { const uint8_t *p = &header[128*z + x*4]; - size_t offset = (p[0] << 16) | (p[1] << 8) | p[2]; + uint32_t offset = (p[0] << 16) | (p[1] << 8) | p[2]; if (!offset) continue; - size_t len = p[3]; + uint8_t len = p[3]; map.emplace(offset, ChunkDesc(x, z, len)); } @@ -61,8 +61,9 @@ void Region::visitChunks(const char *filename, const ChunkVisitor &visitor) { continue; } - size_t x, z, len; - std::tie(x, z, len) = it->second; + chunk_idx_t x = std::get<0>(it->second); + chunk_idx_t z = std::get<1>(it->second); + size_t len = std::get<2>(it->second); if (seen[x][z]) throw std::invalid_argument("duplicate chunk"); diff --git a/src/World/Region.hpp b/src/World/Region.hpp index 7681bbc..22840e8 100644 --- a/src/World/Region.hpp +++ b/src/World/Region.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -21,15 +21,16 @@ namespace World { class Region { public: - static const size_t SIZE = 32; + // Number of chunks in a region in each dimension + static const uint32_t SIZE = 32; - typedef std::function ChunkVisitor; + typedef std::function ChunkVisitor; Region() = delete; private: - typedef std::tuple ChunkDesc; - typedef std::unordered_map ChunkMap; + typedef std::tuple ChunkDesc; + typedef std::unordered_map ChunkMap; static ChunkMap processHeader(const uint8_t header[4096]); diff --git a/src/World/Section.cpp b/src/World/Section.cpp index dbf633f..948fee3 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015-2019, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -8,7 +8,6 @@ #include "Section.hpp" #include "../NBT/ByteTag.hpp" #include "../NBT/StringTag.hpp" -#include "../Util.hpp" #include @@ -21,7 +20,7 @@ Section::Section(const std::shared_ptr §ion) { blockLight = section->get("BlockLight"); } -const Resource::BlockType * Section::getBlockStateAt(size_t, size_t, size_t) const { +const Resource::BlockType * Section::getBlockStateAt(block_idx_t, block_idx_t, block_idx_t) const { return nullptr; } @@ -44,7 +43,7 @@ std::unique_ptr
Section::makeSection(const std::shared_ptr> 3; - size_t shift = bitIndex & 7; + unsigned shift = bitIndex & 7; uint16_t mask = (1u << bits) - 1; uint32_t v = blockStates->getPointer()[mangleByteIndex(pos)]; diff --git a/src/World/Section.hpp b/src/World/Section.hpp index 0791c26..d18f95f 100644 --- a/src/World/Section.hpp +++ b/src/World/Section.hpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2015-2019, Matthias Schiffer + Copyright (c) 2015-2021, Matthias Schiffer All rights reserved. */ @@ -13,6 +13,7 @@ #include "../NBT/ListTag.hpp" #include "../NBT/LongArrayTag.hpp" #include "../Resource/BlockType.hpp" +#include "../Util.hpp" #include #include @@ -23,21 +24,22 @@ namespace World { class Section { public: - static const size_t SIZE = 16; + // Number of blocks in a section in each dimension + static const uint32_t SIZE = 16; private: - size_t Y; + section_idx_t Y; std::shared_ptr blockLight; protected: - static size_t getIndex(size_t x, size_t y, size_t z) { + static size_t getIndex(block_idx_t x, block_idx_t y, block_idx_t z) { if (x >= SIZE || y >= SIZE || z >= SIZE) throw std::range_error("Chunk::getIndex(): bad coordinates"); return SIZE*SIZE*y + SIZE*z + x; } - static uint8_t getHalf(const uint8_t *v, size_t x, size_t y, size_t z) { + static uint8_t getHalf(const uint8_t *v, block_idx_t x, block_idx_t y, block_idx_t z) { size_t i = getIndex(x, y, z); if (i % 2) @@ -51,11 +53,11 @@ protected: public: virtual ~Section() {} - size_t getY() const { return Y; }; + section_idx_t getY() const { return Y; }; - virtual const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const; + virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; - uint8_t getBlockLightAt(size_t x, size_t y, size_t z) const { + uint8_t getBlockLightAt(block_idx_t x, block_idx_t y, block_idx_t z) const { if (!blockLight) return 0; @@ -71,11 +73,11 @@ private: std::shared_ptr data; - uint8_t getBlockAt(size_t x, size_t y, size_t z) const { + uint8_t getBlockAt(block_idx_t x, block_idx_t y, block_idx_t z) const { return blocks->getValue(getIndex(x, y, z)); } - uint8_t getDataAt(size_t x, size_t y, size_t z) const { + uint8_t getDataAt(block_idx_t x, block_idx_t y, block_idx_t z) const { return getHalf(data->getPointer(), x, y, z); } @@ -86,7 +88,7 @@ public: std::shared_ptr &&data0 ) : Section(section), blocks(blocks0), data(data0) {} - virtual const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const; + virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; }; class PaletteSection : public Section { @@ -111,7 +113,7 @@ public: uint32_t dataVersion0 ); - virtual const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const; + virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; }; } diff --git a/src/regiondump.cpp b/src/regiondump.cpp index 8e3deb4..76df061 100644 --- a/src/regiondump.cpp +++ b/src/regiondump.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause /* - Copyright (c) 2018, Matthias Schiffer + Copyright (c) 2018-2021, Matthias Schiffer All rights reserved. */ @@ -23,7 +23,7 @@ int main(int argc, char *argv[]) { return 1; } - World::Region::visitChunks(argv[1], [&] (size_t X, size_t Z, const World::ChunkData *chunk) { + World::Region::visitChunks(argv[1], [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { std::cout << "Chunk(" << X << ", " << Z << "): " << chunk->getRoot() << std::endl; }); From 0f6c467566ab4765df340f6c9f4b11f084aca1f1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 17 Nov 2021 13:16:00 +0100 Subject: [PATCH 019/460] World: Chunk: replace division/modulo with shift/mask for height values Preparation for negative y coordinates. --- src/World/Chunk.cpp | 14 +++++++------- src/World/Chunk.hpp | 15 ++++++++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index e99af79..3845c9b 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -53,7 +53,7 @@ uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { throw std::invalid_argument("corrupt chunk data"); if (biomeInts) - return biomeInts->getValue((y/BGROUP)*BSIZE*BSIZE + (z/BGROUP)*BSIZE + (x/BGROUP)); + return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT)); else if (biomeIntsPre115) return biomeIntsPre115->getValue(z*SIZE + x); else if (biomeBytes) @@ -67,14 +67,14 @@ Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const block.depth = height.depth; - section_idx_t Y = height.y / SIZE; - block_idx_t y = height.y % SIZE; + section_idx_t Y = height.y >> HSHIFT; + block_idx_t y = height.y & HMASK; if (Y < sections.size() && sections[Y]) block.type = sections[Y]->getBlockStateAt(x, y, z); - section_idx_t Yt = (height.y + 1) / SIZE; - block_idx_t yt = (height.y + 1) % SIZE; + section_idx_t Yt = (height.y + 1) >> HSHIFT; + block_idx_t yt = (height.y + 1) & HMASK; if (Yt < sections.size() && sections[Yt]) block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); @@ -97,7 +97,7 @@ bool Chunk::getHeight( return false; if (height->y == 0) - height->y = SIZE*section->getY() + y; + height->y = (section->getY() << HSHIFT) + y; if (!(flags & WITH_DEPTH)) return true; @@ -105,7 +105,7 @@ bool Chunk::getHeight( if (type->flags & BLOCK_WATER) return false; - height->depth = SIZE*section->getY() + y; + height->depth = (section->getY() << HSHIFT) + y; return true; } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 26d10d1..817b29f 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -29,13 +29,18 @@ public: // Maximum Y value static const y_idx_t MAXY = 256; + // Shift to get from height to section index + static const unsigned HSHIFT = 4; + // Mask to get from height to y index inside section + static const block_idx_t HMASK = 0xf; + // Since Minecraft 1.15, biome information is stored for // 4x4x4 block groups - static const uint32_t BGROUP = 4; + static const unsigned BSHIFT = 2; // Number of biome values in a chunk in x/z dimensions - static const uint32_t BSIZE = SIZE / BGROUP; + static const uint32_t BSIZE = SIZE >> BSHIFT; // Number of biome values in a chunk in y dimension - static const uint32_t BMAXY = MAXY / BGROUP; + static const uint32_t BMAXY = MAXY >> BSHIFT; // Flags static const int WITH_DEPTH = (1 << 0); @@ -63,12 +68,12 @@ private: ) const; const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const { - section_idx_t Y = y / SIZE; + section_idx_t Y = y >> HSHIFT; if (Y >= sections.size() || !sections[Y]) return nullptr; - return sections[Y]->getBlockStateAt(x, y % SIZE, z); + return sections[Y]->getBlockStateAt(x, y & HMASK, z); } From 16a1258f082b1e37e82757f559cfc1b1f9d4ba91 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Dec 2021 23:45:31 +0100 Subject: [PATCH 020/460] World: Chunk: remove unnecessary level class member --- src/World/Chunk.cpp | 3 ++- src/World/Chunk.hpp | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 3845c9b..c326669 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -18,7 +18,8 @@ namespace MinedMap { namespace World { Chunk::Chunk(const ChunkData *data) { - level = assertValue(data->getRoot().get("Level")); + std::shared_ptr level = + assertValue(data->getRoot().get("Level")); std::shared_ptr sectionsTag = level->get("Sections"); if (!sectionsTag || sectionsTag->empty()) diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 817b29f..cfae0f7 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -55,7 +55,6 @@ public: }; private: - std::shared_ptr level; std::vector> sections; std::shared_ptr biomeBytes; @@ -80,10 +79,6 @@ private: public: Chunk(const ChunkData *data); - const NBT::CompoundTag & getLevel() const { - return *level; - } - uint8_t getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const; Block getBlock(block_idx_t x, Height y, block_idx_t z) const; From 21966252ea6cede058b4b2c4323e0dc4a76747d9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Dec 2021 23:54:15 +0100 Subject: [PATCH 021/460] World: ChunkData: make getRoot() return shared pointer reference --- src/World/Chunk.cpp | 4 ++-- src/World/ChunkData.hpp | 4 ++-- src/regiondump.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index c326669..fc0307e 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -19,7 +19,7 @@ namespace World { Chunk::Chunk(const ChunkData *data) { std::shared_ptr level = - assertValue(data->getRoot().get("Level")); + assertValue(data->getRoot()->get("Level")); std::shared_ptr sectionsTag = level->get("Sections"); if (!sectionsTag || sectionsTag->empty()) @@ -37,7 +37,7 @@ Chunk::Chunk(const ChunkData *data) { else throw std::invalid_argument("corrupt biome data"); - auto dataVersionTag = data->getRoot().get("DataVersion"); + auto dataVersionTag = data->getRoot()->get("DataVersion"); uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0; for (auto &sTag : *sectionsTag) { diff --git a/src/World/ChunkData.hpp b/src/World/ChunkData.hpp index cb27f7b..62a69c1 100644 --- a/src/World/ChunkData.hpp +++ b/src/World/ChunkData.hpp @@ -32,8 +32,8 @@ private: public: ChunkData(Buffer buffer); - const NBT::CompoundTag & getRoot() const { - return *root; + const std::shared_ptr & getRoot() const { + return root; } }; diff --git a/src/regiondump.cpp b/src/regiondump.cpp index 76df061..a091536 100644 --- a/src/regiondump.cpp +++ b/src/regiondump.cpp @@ -25,7 +25,7 @@ int main(int argc, char *argv[]) { World::Region::visitChunks(argv[1], [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { std::cout << "Chunk(" << X << ", " << Z << "): " - << chunk->getRoot() << std::endl; + << *chunk->getRoot() << std::endl; }); return 0; From 9ee1007ade7f29972ab07df5e2436d8e824a58a9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Dec 2021 00:03:47 +0100 Subject: [PATCH 022/460] World: Chunk: use enum to store biome data format --- src/World/Chunk.cpp | 26 ++++++++++++++++---------- src/World/Chunk.hpp | 8 +++++++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index fc0307e..8b4b9eb 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -28,14 +28,18 @@ Chunk::Chunk(const ChunkData *data) { auto biomesIntArray = level->get("Biomes"); auto biomesByteArray = level->get("Biomes"); - if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) + if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) { biomeInts = std::move(biomesIntArray); - else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) - biomeIntsPre115 = std::move(biomesIntArray); - else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) + biomeFormat = INT_ARRAY; + } else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) { + biomeInts = std::move(biomesIntArray); + biomeFormat = INT_ARRAY_PRE1_15; + } else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) { biomeBytes = std::move(biomesByteArray); - else + biomeFormat = BYTE_ARRAY; + } else { throw std::invalid_argument("corrupt biome data"); + } auto dataVersionTag = data->getRoot()->get("DataVersion"); uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0; @@ -53,14 +57,16 @@ uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { if (x > SIZE || y > MAXY || z > SIZE) throw std::invalid_argument("corrupt chunk data"); - if (biomeInts) + switch (biomeFormat) { + case INT_ARRAY: return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT)); - else if (biomeIntsPre115) - return biomeIntsPre115->getValue(z*SIZE + x); - else if (biomeBytes) + case INT_ARRAY_PRE1_15: + return biomeInts->getValue(z*SIZE + x); + case BYTE_ARRAY: return biomeBytes->getValue(z*SIZE + x); - else + default: return 0xff; + } } Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const { diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index cfae0f7..1a59efe 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -57,8 +57,14 @@ public: private: std::vector> sections; + enum BiomeFormat { + UNKNOWN = 0, + BYTE_ARRAY, + INT_ARRAY_PRE1_15, + INT_ARRAY, + } biomeFormat = UNKNOWN; + std::shared_ptr biomeBytes; - std::shared_ptr biomeIntsPre115; std::shared_ptr biomeInts; bool getHeight( From aacea26716b5dc94e8d00bbef16c70797797d831 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Dec 2021 00:16:16 +0100 Subject: [PATCH 023/460] World: add support for negative Y coordinates and MC 1.18 chunks MC 1.18 biomes are not handled yet. --- src/Util.hpp | 7 ++-- src/World/Chunk.cpp | 83 ++++++++++++++++++++++++++++--------------- src/World/Chunk.hpp | 8 +++-- src/World/Section.cpp | 37 +++++++++++++------ src/regiondump.cpp | 2 +- 5 files changed, 92 insertions(+), 45 deletions(-) diff --git a/src/Util.hpp b/src/Util.hpp index 1f50958..163813d 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -29,13 +30,15 @@ static inline float clamp(float v, float min, float max) { // A block coordinate relative to a chunk/section (X/Y/Z) typedef uint8_t block_idx_t; // A section index in a chunk (Y) -typedef uint8_t section_idx_t; +typedef int8_t section_idx_t; // A chunk coordinate relative to a region (X/Z) typedef uint8_t chunk_idx_t; // A block coordinate relative to a region (X/Z) typedef uint16_t region_block_idx_t; // A block coordinate (Y) -typedef uint16_t y_idx_t; +typedef int16_t y_idx_t; + +const y_idx_t y_idx_min = std::numeric_limits::min(); } diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 8b4b9eb..a447cda 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -18,27 +18,35 @@ namespace MinedMap { namespace World { Chunk::Chunk(const ChunkData *data) { - std::shared_ptr level = - assertValue(data->getRoot()->get("Level")); + std::shared_ptr sectionsTag; - std::shared_ptr sectionsTag = level->get("Sections"); - if (!sectionsTag || sectionsTag->empty()) - return; + auto level = data->getRoot()->get("Level"); + if (level) { + sectionsTag = level->get("Sections"); + if (!sectionsTag || sectionsTag->empty()) + return; - auto biomesIntArray = level->get("Biomes"); - auto biomesByteArray = level->get("Biomes"); + auto biomesIntArray = level->get("Biomes"); + auto biomesByteArray = level->get("Biomes"); - if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) { - biomeInts = std::move(biomesIntArray); - biomeFormat = INT_ARRAY; - } else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) { - biomeInts = std::move(biomesIntArray); - biomeFormat = INT_ARRAY_PRE1_15; - } else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) { - biomeBytes = std::move(biomesByteArray); - biomeFormat = BYTE_ARRAY; + if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) { + biomeInts = std::move(biomesIntArray); + biomeFormat = INT_ARRAY; + } else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) { + biomeInts = std::move(biomesIntArray); + biomeFormat = INT_ARRAY_PRE1_15; + } else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) { + biomeBytes = std::move(biomesByteArray); + biomeFormat = BYTE_ARRAY; + } else { + throw std::invalid_argument("corrupt biome data"); + } } else { - throw std::invalid_argument("corrupt biome data"); + sectionsTag = data->getRoot()->get("sections"); + if (!sectionsTag || sectionsTag->empty()) + return; + + biomeFormat = SECTION; } auto dataVersionTag = data->getRoot()->get("DataVersion"); @@ -48,25 +56,34 @@ Chunk::Chunk(const ChunkData *data) { auto s = std::dynamic_pointer_cast(sTag); std::unique_ptr
section = Section::makeSection(s, dataVersion); section_idx_t Y = section->getY(); + if (sections.empty()) + sectionOffset = Y; + + Y -= sectionOffset; + assertValue(Y >= 0 && size_t(Y) >= sections.size()); sections.resize(Y); sections.push_back(std::move(section)); } } uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { - if (x > SIZE || y > MAXY || z > SIZE) - throw std::invalid_argument("corrupt chunk data"); + if (x >= SIZE || z >= SIZE) + throw std::invalid_argument("getBiome: invalid block coordinate"); switch (biomeFormat) { case INT_ARRAY: + if (y < 0 || y >= MAXY) + break; return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT)); case INT_ARRAY_PRE1_15: return biomeInts->getValue(z*SIZE + x); case BYTE_ARRAY: return biomeBytes->getValue(z*SIZE + x); default: - return 0xff; + break; } + + return 0xff; } Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const { @@ -74,16 +91,19 @@ Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const block.depth = height.depth; - section_idx_t Y = height.y >> HSHIFT; + if (height.y == y_idx_min) + return block; + + section_idx_t Y = (height.y >> HSHIFT) - sectionOffset; block_idx_t y = height.y & HMASK; - if (Y < sections.size() && sections[Y]) + if (Y >= 0 && size_t(Y) < sections.size() && sections[Y]) block.type = sections[Y]->getBlockStateAt(x, y, z); - section_idx_t Yt = (height.y + 1) >> HSHIFT; + section_idx_t Yt = ((height.y + 1) >> HSHIFT) - sectionOffset; block_idx_t yt = (height.y + 1) & HMASK; - if (Yt < sections.size() && sections[Yt]) + if (Yt >= 0 && size_t(Yt) < sections.size() && sections[Yt]) block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); return block; @@ -93,17 +113,17 @@ bool Chunk::getHeight( Chunk::Height *height, const Section *section, block_idx_t x, block_idx_t y, block_idx_t z, int flags ) const { - if (height->depth > 0) + if (height->depth > y_idx_min) return false; - if (!(flags & WITH_DEPTH) && height->y > 0) + if (!(flags & WITH_DEPTH) && height->y > y_idx_min) return false; const Resource::BlockType *type = section->getBlockStateAt(x, y, z); if (!type || !(type->flags & BLOCK_OPAQUE)) return false; - if (height->y == 0) + if (height->y == y_idx_min) height->y = (section->getY() << HSHIFT) + y; if (!(flags & WITH_DEPTH)) @@ -119,9 +139,14 @@ bool Chunk::getHeight( Chunk::Heightmap Chunk::getTopLayer(int flags) const { uint32_t done = 0; - Heightmap ret = {}; + Heightmap ret; - for (int16_t Y = sections.size() - 1; Y >= 0; Y--) { + for (block_idx_t z = 0; z < SIZE; z++) { + for (block_idx_t x = 0; x < SIZE; x++) + ret.v[x][z] = Height { .y = y_idx_min, .depth = y_idx_min }; + } + + for (section_idx_t Y = sections.size() - 1; Y >= 0; Y--) { if (done == SIZE*SIZE) break; diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 1a59efe..34a5184 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -26,7 +26,7 @@ class Chunk { public: // Number of blocks in a chunk in x/z dimensions static const uint32_t SIZE = Section::SIZE; - // Maximum Y value + // Maximum Y value for pre-1.18 chunks static const y_idx_t MAXY = 256; // Shift to get from height to section index @@ -55,6 +55,7 @@ public: }; private: + section_idx_t sectionOffset; std::vector> sections; enum BiomeFormat { @@ -62,6 +63,7 @@ private: BYTE_ARRAY, INT_ARRAY_PRE1_15, INT_ARRAY, + SECTION, } biomeFormat = UNKNOWN; std::shared_ptr biomeBytes; @@ -73,9 +75,9 @@ private: ) const; const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const { - section_idx_t Y = y >> HSHIFT; + section_idx_t Y = (y >> HSHIFT) - sectionOffset; - if (Y >= sections.size() || !sections[Y]) + if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y]) return nullptr; return sections[Y]->getBlockStateAt(x, y & HMASK, z); diff --git a/src/World/Section.cpp b/src/World/Section.cpp index 948fee3..bc10f96 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -16,7 +16,7 @@ namespace MinedMap { namespace World { Section::Section(const std::shared_ptr §ion) { - Y = assertValue(section->get("Y"))->getValue(); + Y = int8_t(assertValue(section->get("Y"))->getValue()); blockLight = section->get("BlockLight"); } @@ -25,18 +25,32 @@ const Resource::BlockType * Section::getBlockStateAt(block_idx_t, block_idx_t, b } std::unique_ptr
Section::makeSection(const std::shared_ptr §ion, uint32_t dataVersion) { - std::shared_ptr blockStates = section->get("BlockStates"); - if (blockStates) { - const std::shared_ptr palette = assertValue(section->get("Palette")); + { + const std::shared_ptr blockStates = section->get("block_states"); + if (blockStates) { + const std::shared_ptr palette = assertValue(blockStates->get("palette")); + std::shared_ptr data = blockStates->get("data"); - return std::unique_ptr
(new PaletteSection(section, std::move(blockStates), palette, dataVersion)); + return std::unique_ptr
(new PaletteSection(section, std::move(data), palette, dataVersion)); + } } - std::shared_ptr blocks = section->get("Blocks"); - if (blocks) { - std::shared_ptr data = assertValue(section->get("Data")); + { + std::shared_ptr blockStates = section->get("BlockStates"); + if (blockStates) { + const std::shared_ptr palette = assertValue(section->get("Palette")); - return std::unique_ptr
(new LegacySection(section, std::move(blocks), std::move(data))); + return std::unique_ptr
(new PaletteSection(section, std::move(blockStates), palette, dataVersion)); + } + } + + { + std::shared_ptr blocks = section->get("Blocks"); + if (blocks) { + std::shared_ptr data = assertValue(section->get("Data")); + + return std::unique_ptr
(new LegacySection(section, std::move(blocks), std::move(data))); + } } return std::unique_ptr
(new Section(section)); @@ -81,7 +95,7 @@ PaletteSection::PaletteSection( expectedLength = (4096 + blocksPerWord - 1) / blocksPerWord; } - if (blockStates->getLength() != expectedLength) + if (blockStates && blockStates->getLength() != expectedLength) throw std::invalid_argument("corrupt section data"); for (const auto &entry : *paletteData) { @@ -97,6 +111,9 @@ PaletteSection::PaletteSection( } const Resource::BlockType * PaletteSection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const { + if (!blockStates) + return palette.at(0); + size_t index = getIndex(x, y, z); size_t bitIndex; diff --git a/src/regiondump.cpp b/src/regiondump.cpp index a091536..62fe359 100644 --- a/src/regiondump.cpp +++ b/src/regiondump.cpp @@ -24,7 +24,7 @@ int main(int argc, char *argv[]) { } World::Region::visitChunks(argv[1], [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { - std::cout << "Chunk(" << X << ", " << Z << "): " + std::cout << "Chunk(" << unsigned(X) << ", " << unsigned(Z) << "): " << *chunk->getRoot() << std::endl; }); From 76e5d322b142bfdc19509fc4e53cf212d6ef7483 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 9 Dec 2021 02:07:20 +0100 Subject: [PATCH 024/460] Resource: Biome: add biome palette name mapping For now we will continue to use the numerical biome IDs internally, as our biome storage format is based on these IDs. --- src/Resource/Biome.cpp | 130 ++++++++++++++++++++++++++++++++++++++--- src/Resource/Biome.hpp | 8 ++- src/World/Block.hpp | 2 +- 3 files changed, 128 insertions(+), 12 deletions(-) diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index 3cf1586..d871ad5 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -10,7 +10,6 @@ #include "BlockType.hpp" - namespace MinedMap { namespace Resource { @@ -145,9 +144,19 @@ static const Biome BiomeWarmOcean(0.8f, 0.5f, {0.263f, 0.835f, 0.933f}); static const Biome BiomeLukewarmOcean(0.8f, 0.5f, {0.271f, 0.678f, 0.949f}); static const Biome BiomeColdOcean(0.8f, 0.5f, {0.239f, 0.341f, 0.839f}); -extern const Biome *const BIOME_DEFAULT = &BiomeDefault; +static const Biome BiomeMeadow(0.5f, 0.8f); +static const Biome BiomeGrove(-0.2f, 0.8f); +static const Biome BiomeJaggedPeaks(-0.7f, 0.9f); +static const Biome BiomeStonyPeaks(1.0f, 0.3f); +static const Biome BiomeSnowySlopes(-0.3f, 0.9f); -const Biome *const BIOMES[256] = { +const Biome *const Biome::Default = &BiomeDefault; + +/* Minecraft 1.18 does not use numerical IDs for biomes anymore. + * Previously unused biome IDs are assigned to the new biome types of + * Minecraft 1.18 for storage in MinedMap's biome data cache. */ + +const Biome *const Biome::Biomes[256] = { /* 0 */ &BiomeDefault, /* Ocean */ /* 1 */ &BiomePlains, /* 2 */ &BiomeDesert, @@ -199,11 +208,11 @@ const Biome *const BIOMES[256] = { /* 48 */ &BiomeLukewarmOcean, /* Deep Lukewarm Ocean */ /* 49 */ &BiomeColdOcean, /* Deep Cold Ocean */ /* 50 */ &BiomeFrozenOcean, /* Deep Frozen Ocean */ - /* 51 */ nullptr, - /* 52 */ nullptr, - /* 53 */ nullptr, - /* 54 */ nullptr, - /* 55 */ nullptr, + /* 51 */ &BiomeMeadow, /* MinedMap assignment */ + /* 52 */ &BiomeGrove, /* MinedMap assignment */ + /* 53 */ &BiomeJaggedPeaks, /* MinedMap assignment */ + /* 54 */ &BiomeStonyPeaks, /* MinedMap assignment */ + /* 55 */ &BiomeSnowySlopes, /* MinedMap assignment */ /* 56 */ nullptr, /* 57 */ nullptr, /* 58 */ nullptr, @@ -326,5 +335,110 @@ const Biome *const BIOMES[256] = { /* 175 */ &BiomeDefault, /* Lush Caves */ }; +/* It is unclear which of the renamed/merged biome IDs can appear in practice, + * but it shouldn't hurt to support them anyways */ + +const std::unordered_map Biome::Names = { + { "minecraft:badlands", 37 }, + { "minecraft:badlands_plateau", 39 }, /* 1.18: Merged into badlands */ + { "minecraft:bamboo_jungle", 168 }, + { "minecraft:bamboo_jungle_hills", 169 }, /* 1.18: Merged into bamboo_jungle */ + { "minecraft:basalt_deltas", 173 }, + { "minecraft:beach", 16 }, + { "minecraft:birch_forest", 27 }, + { "minecraft:birch_forest_hills", 28 }, /* 1.18: Merged into birch_forest */ + { "minecraft:cold_ocean", 46 }, + { "minecraft:crimson_forest", 171 }, + { "minecraft:dark_forest", 29 }, + { "minecraft:dark_forest_hills", 157 }, /* 1.18: Merged into dark_forest */ + { "minecraft:deep_cold_ocean", 49 }, + { "minecraft:deep_frozen_ocean", 50 }, + { "minecraft:deep_lukewarm_ocean", 48 }, + { "minecraft:deep_ocean", 24 }, + { "minecraft:deep_warm_ocean", 47 }, /* 1.18: Merged into warm_ocean */ + { "minecraft:desert", 2 }, + { "minecraft:desert_hills", 17 }, /* 1.18: Merged into desert */ + { "minecraft:desert_lakes", 130 }, /* 1.18: Merged into desert */ + { "minecraft:dripstone_caves", 174 }, + { "minecraft:end_barrens", 43 }, + { "minecraft:end_highlands", 42 }, + { "minecraft:end_midlands", 41 }, + { "minecraft:eroded_badlands", 165 }, + { "minecraft:extreme_hills", 3 }, /* 1.18: Renamed to windswept_hills (after rename from mountains) */ + { "minecraft:flower_forest", 132 }, + { "minecraft:forest", 4 }, + { "minecraft:frozen_ocean", 10 }, + { "minecraft:frozen_peaks", 53 }, /* 1.18: New */ + { "minecraft:frozen_river", 11 }, + { "minecraft:giant_spruce_taiga", 160 }, /* 1.18: Renamed to old_growth_spruce_taiga */ + { "minecraft:giant_spruce_taiga_hills", 161 }, /* 1.18: Merged into giant_spruce_taiga */ + { "minecraft:giant_tree_taiga", 32 }, /* 1.18: Renamed to old_growth_pine_taiga */ + { "minecraft:giant_tree_taiga_hills", 33 }, /* 1.18: Merged into giant_tree_taiga */ + { "minecraft:gravelly_mountains", 131 }, /* 1.18: Renamed to windswept_gravelly_hills */ + { "minecraft:grove", 52 }, /* 1.18: New */ + { "minecraft:ice_spikes", 140 }, + { "minecraft:jagged_peaks", 53 }, /* 1.18: New */ + { "minecraft:jungle", 21 }, + { "minecraft:jungle_edge", 23 }, /* 1.18: Renamed to sparse_jungle */ + { "minecraft:jungle_hills", 22 }, /* 1.18: Merged into jungle */ + { "minecraft:lukewarm_ocean", 45 }, + { "minecraft:lush_caves", 175 }, + { "minecraft:meadow", 51 }, /* 1.18: New */ + { "minecraft:modified_badlands_plateau", 167 }, /* 1.18: Merged into badlands */ + { "minecraft:modified_gravelly_mountains", 162 }, /* 1.18: Merged into gravelly_mountains */ + { "minecraft:modified_jungle", 149 }, /* 1.18: Merged into jungle */ + { "minecraft:modified_jungle_edge", 151 }, /* 1.18: Merged into jungle_edge */ + { "minecraft:modified_wooded_badlands_plateau", 166 }, /* 1.18: Merged into wooded_badlands */ + { "minecraft:mountain_edge", 20 }, /* 1.18: Merged into mountains */ + { "minecraft:mountains", 3 }, /* 1.18: Renamed to windswept_hills */ + { "minecraft:mushroom_field_shore", 15 }, /* 1.18: Merged into mushroom_fields */ + { "minecraft:mushroom_fields", 14 }, + { "minecraft:nether_wastes", 8 }, + { "minecraft:ocean", 0 }, + { "minecraft:old_growth_birch_forest", 155 }, + { "minecraft:old_growth_pine_taiga", 32 }, + { "minecraft:old_growth_spruce_taiga", 160 }, + { "minecraft:plains", 1 }, + { "minecraft:river", 7 }, + { "minecraft:savanna", 35 }, + { "minecraft:savanna_plateau", 36 }, + { "minecraft:shattered_savanna", 163 }, + { "minecraft:shattered_savanna_plateau", 164 }, /* 1.18: Merged into shattered_savanna */ + { "minecraft:small_end_islands", 40 }, + { "minecraft:snowy_beach", 26 }, + { "minecraft:snowy_mountains", 13 }, /* 1.18: Merged into snowy_tundra */ + { "minecraft:snowy_plains", 12 }, + { "minecraft:snowy_slopes", 55 }, + { "minecraft:snowy_taiga", 30 }, + { "minecraft:snowy_taiga_hills", 31 }, /* 1.18: Merged into snowy_taiga */ + { "minecraft:snowy_taiga_mountains", 158 }, /* 1.18: Merged into snowy_taiga */ + { "minecraft:snowy_tundra", 12 }, + { "minecraft:soul_sand_valley", 170 }, + { "minecraft:sparse_jungle", 23 }, + { "minecraft:stone_shore", 25 }, + { "minecraft:stony_peaks", 54 }, /* 1.18: New */ + { "minecraft:stony_shore", 25 }, + { "minecraft:sunflower_plains", 129 }, + { "minecraft:swamp", 6 }, + { "minecraft:swamp_hills", 134 }, /* 1.18: Merged into swamp */ + { "minecraft:taiga", 5 }, + { "minecraft:taiga_hills", 19 }, /* 1.18: Merged into taiga */ + { "minecraft:taiga_mountains", 133 }, /* 1.18: Merged into taiga */ + { "minecraft:tall_birch_forest", 155 }, /* 1.18: Renamed to old_growth_birch_forest */ + { "minecraft:tall_birch_hills", 156 }, /* 1.18: Merged into tall_birch_forest */ + { "minecraft:the_end", 9 }, + { "minecraft:the_void", 127 }, + { "minecraft:warm_ocean", 44 }, + { "minecraft:warped_forest", 172 }, + { "minecraft:windswept_forest", 34 }, + { "minecraft:windswept_gravelly_hills", 131 }, + { "minecraft:windswept_hills", 3 }, + { "minecraft:windswept_savanna", 163 }, + { "minecraft:wooded_badlands", 38 }, + { "minecraft:wooded_badlands_plateau", 38 }, /* 1.18: Renamed to wooded_badlands */ + { "minecraft:wooded_hills", 18 }, /* 1.18: Merged into forest */ + { "minecraft:wooded_mountains", 34 /* 1.18: Renamed to windswept_forest */}, +}; + } } diff --git a/src/Resource/Biome.hpp b/src/Resource/Biome.hpp index 490668c..0cb4f8c 100644 --- a/src/Resource/Biome.hpp +++ b/src/Resource/Biome.hpp @@ -10,6 +10,7 @@ #include "Color.hpp" #include "../Util.hpp" +#include namespace MinedMap { namespace Resource { @@ -28,14 +29,15 @@ protected: FloatColor getWaterColor() const { return water; }; public: + static const Biome *const Default; + static const Biome *const Biomes[256]; + static const std::unordered_map Names; + Biome(float temp0, float rain0, FloatColor water0 = {0.247f, 0.463f, 0.894f}) : temp(temp0), rain(rain0), water(water0) {} FloatColor getBlockColor(const BlockType *type, y_idx_t height) const; }; -extern const Biome *const BIOME_DEFAULT; -extern const Biome *const BIOMES[256]; - } } diff --git a/src/World/Block.hpp b/src/World/Block.hpp index 2f207a3..e1ed09a 100644 --- a/src/World/Block.hpp +++ b/src/World/Block.hpp @@ -28,7 +28,7 @@ struct Block { if (!isVisible()) return Resource::FloatColor {}; - return (Resource::BIOMES[biome] ?: Resource::BIOME_DEFAULT)->getBlockColor(type, depth); + return (Resource::Biome::Biomes[biome] ?: Resource::Biome::Default)->getBlockColor(type, depth); } operator bool() const { From baa20494bf5e4c98b220065d3a2813a3a36378c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Dec 2021 19:34:38 +0100 Subject: [PATCH 025/460] World: Section: implement new section-based biome data format --- src/World/Chunk.cpp | 8 +++++ src/World/Chunk.hpp | 4 +-- src/World/Section.cpp | 83 ++++++++++++++++++++++++++++++++++++++++--- src/World/Section.hpp | 26 ++++++++++++-- 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index a447cda..136c3bf 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -79,6 +79,14 @@ uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { return biomeInts->getValue(z*SIZE + x); case BYTE_ARRAY: return biomeBytes->getValue(z*SIZE + x); + case SECTION: { + section_idx_t Y = (y >> HSHIFT) - sectionOffset; + + if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y]) + break; + + return sections[Y]->getBiomeAt(x, y & HMASK, z); + } default: break; } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 34a5184..611c3c8 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -36,9 +36,9 @@ public: // Since Minecraft 1.15, biome information is stored for // 4x4x4 block groups - static const unsigned BSHIFT = 2; + static const unsigned BSHIFT = Section::BSHIFT; // Number of biome values in a chunk in x/z dimensions - static const uint32_t BSIZE = SIZE >> BSHIFT; + static const uint32_t BSIZE = Section::BSIZE; // Number of biome values in a chunk in y dimension static const uint32_t BMAXY = MAXY >> BSHIFT; diff --git a/src/World/Section.cpp b/src/World/Section.cpp index bc10f96..8d50bca 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -6,6 +6,7 @@ #include "Section.hpp" +#include "../Resource/Biome.hpp" #include "../NBT/ByteTag.hpp" #include "../NBT/StringTag.hpp" @@ -24,6 +25,10 @@ const Resource::BlockType * Section::getBlockStateAt(block_idx_t, block_idx_t, b return nullptr; } +uint8_t Section::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const { + return 0xff; +} + std::unique_ptr
Section::makeSection(const std::shared_ptr §ion, uint32_t dataVersion) { { const std::shared_ptr blockStates = section->get("block_states"); @@ -31,7 +36,13 @@ std::unique_ptr
Section::makeSection(const std::shared_ptr palette = assertValue(blockStates->get("palette")); std::shared_ptr data = blockStates->get("data"); - return std::unique_ptr
(new PaletteSection(section, std::move(data), palette, dataVersion)); + const std::shared_ptr biomes = assertValue(section->get("biomes")); + const std::shared_ptr biomePalette = assertValue(biomes->get("palette")); + std::shared_ptr biomeData = biomes->get("data"); + + return std::unique_ptr
(new PaletteSection( + section, std::move(data), palette, std::move(biomeData), biomePalette, dataVersion + )); } } @@ -40,7 +51,10 @@ std::unique_ptr
Section::makeSection(const std::shared_ptr palette = assertValue(section->get("Palette")); - return std::unique_ptr
(new PaletteSection(section, std::move(blockStates), palette, dataVersion)); + return std::unique_ptr
(new PaletteSection( + section, std::move(blockStates), palette, + std::shared_ptr(), std::shared_ptr(), dataVersion + )); } } @@ -76,8 +90,10 @@ PaletteSection::PaletteSection( const std::shared_ptr §ion, std::shared_ptr &&blockStates0, const std::shared_ptr &paletteData, + std::shared_ptr &&biomes0, + const std::shared_ptr &biomePaletteData, uint32_t dataVersion0 -) : Section(section), blockStates(blockStates0), dataVersion(dataVersion0) { +) : Section(section), blockStates(blockStates0), biomes(biomes0), dataVersion(dataVersion0) { bits = 4; while ((1u << bits) < paletteData->size()) { bits++; @@ -86,6 +102,16 @@ PaletteSection::PaletteSection( throw std::invalid_argument("unsupported block palette size"); } + biomeBits = 1; + if (biomePaletteData) { + while ((1u << biomeBits) < biomePaletteData->size()) { + biomeBits++; + + if (bits > 6) + throw std::invalid_argument("unsupported biome palette size"); + } + } + unsigned expectedLength; if (dataVersion < 2529) { @@ -96,7 +122,13 @@ PaletteSection::PaletteSection( } if (blockStates && blockStates->getLength() != expectedLength) - throw std::invalid_argument("corrupt section data"); + throw std::invalid_argument("corrupt section block data"); + + unsigned biomesPerWord = (64 / biomeBits); + unsigned expectedBiomeLength = (64 + biomesPerWord - 1) / biomesPerWord; + + if (biomes && biomes->getLength() != expectedBiomeLength) + throw std::invalid_argument("corrupt section biome data"); for (const auto &entry : *paletteData) { const NBT::CompoundTag &paletteEntry = *assertValue(dynamic_cast(entry.get())); @@ -108,6 +140,25 @@ PaletteSection::PaletteSection( palette.push_back(type); } + + if (biomePaletteData) { + for (const auto &entry : *biomePaletteData) { + const NBT::StringTag &paletteEntry = + *assertValue(dynamic_cast(entry.get())); + std::string name = paletteEntry.getValue(); + + auto it = Resource::Biome::Names.find(name); + uint8_t biome; + if (it != Resource::Biome::Names.end()) { + biome = it->second; + } else { + std::fprintf(stderr, "Warning: unknown biome: %s\n", name.c_str()); + biome = 0xff; + } + + biomePalette.push_back(biome); + } + } } const Resource::BlockType * PaletteSection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const { @@ -141,5 +192,29 @@ const Resource::BlockType * PaletteSection::getBlockStateAt(block_idx_t x, block return palette.at((v >> shift) & mask); } +uint8_t PaletteSection::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const { + if (!biomes) + return biomePalette.at(0); + + size_t index = getBiomeIndex(x, y, z); + + unsigned biomesPerWord = (64 / biomeBits); + size_t word = index / biomesPerWord; + size_t bitIndex = 64 * word + biomeBits * (index % biomesPerWord); + + size_t pos = bitIndex >> 3; + unsigned shift = bitIndex & 7; + uint16_t mask = (1u << biomeBits) - 1; + + uint32_t v = biomes->getPointer()[mangleByteIndex(pos)]; + + if (shift + biomeBits > 8) + v |= biomes->getPointer()[mangleByteIndex(pos + 1)] << 8; + /* We do not need to check for shift+bits > 16: biomeBits should never + be greater than 6, so our value will never span more than 2 bytes */ + + return biomePalette.at((v >> shift) & mask); +} + } } diff --git a/src/World/Section.hpp b/src/World/Section.hpp index d18f95f..9884a77 100644 --- a/src/World/Section.hpp +++ b/src/World/Section.hpp @@ -27,6 +27,13 @@ public: // Number of blocks in a section in each dimension static const uint32_t SIZE = 16; + // Since Minecraft 1.15, biome information is stored for + // 4x4x4 block groups + static const unsigned BSHIFT = 2; + // Number of biome values in a chunk in x/z dimensions + static const uint32_t BSIZE = SIZE >> BSHIFT; + + private: section_idx_t Y; std::shared_ptr blockLight; @@ -34,11 +41,18 @@ private: protected: static size_t getIndex(block_idx_t x, block_idx_t y, block_idx_t z) { if (x >= SIZE || y >= SIZE || z >= SIZE) - throw std::range_error("Chunk::getIndex(): bad coordinates"); + throw std::range_error("Section::getIndex(): bad coordinates"); return SIZE*SIZE*y + SIZE*z + x; } + static size_t getBiomeIndex(block_idx_t x, block_idx_t y, block_idx_t z) { + if (x >= SIZE || y >= SIZE || z >= SIZE) + throw std::range_error("Section::getBiomeIndex(): bad coordinates"); + + return BSIZE*BSIZE*(y>>BSHIFT) + BSIZE*(z>>BSHIFT) + (x>>BSHIFT); + } + static uint8_t getHalf(const uint8_t *v, block_idx_t x, block_idx_t y, block_idx_t z) { size_t i = getIndex(x, y, z); @@ -56,6 +70,7 @@ public: section_idx_t getY() const { return Y; }; virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; + virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const; uint8_t getBlockLightAt(block_idx_t x, block_idx_t y, block_idx_t z) const { if (!blockLight) @@ -95,9 +110,13 @@ class PaletteSection : public Section { private: std::shared_ptr blockStates; std::vector palette; - uint32_t dataVersion; unsigned bits; + std::shared_ptr biomes; + std::vector biomePalette; + unsigned biomeBits; + + uint32_t dataVersion; static const Resource::BlockType * lookup(const std::string &name, uint32_t dataVersion); @@ -110,10 +129,13 @@ public: const std::shared_ptr §ion, std::shared_ptr &&blockStates0, const std::shared_ptr &paletteData, + std::shared_ptr &&biomes0, + const std::shared_ptr &biomePaletteData, uint32_t dataVersion0 ); virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; + virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const; }; } From 73dfecf37988f55b7b94e94e392c97e2d8ec91a0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 11 Dec 2021 19:39:52 +0100 Subject: [PATCH 026/460] Resource: BlockType: update colors with MC1.18 texture data --- src/Resource/BlockType.inc.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Resource/BlockType.inc.cpp b/src/Resource/BlockType.inc.cpp index 0489fd9..9a4ff17 100644 --- a/src/Resource/BlockType.inc.cpp +++ b/src/Resource/BlockType.inc.cpp @@ -131,8 +131,8 @@ {"minecraft:campfire", {BLOCK_OPAQUE, {110, 88, 54}}}, {"minecraft:candle", {0, {0, 0, 0}}}, {"minecraft:candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:carrots", {BLOCK_OPAQUE, {81, 123, 37}}}, -{"minecraft:cartography_table", {BLOCK_OPAQUE, {104, 87, 67}}}, +{"minecraft:carrots", {BLOCK_OPAQUE, {81, 124, 37}}}, +{"minecraft:cartography_table", {BLOCK_OPAQUE, {103, 87, 67}}}, {"minecraft:carved_pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}}, {"minecraft:cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, {"minecraft:cave_air", {0, {0, 0, 0}}}, @@ -193,7 +193,7 @@ {"minecraft:crimson_sign", {BLOCK_OPAQUE, {101, 48, 70}}}, {"minecraft:crimson_slab", {BLOCK_OPAQUE, {101, 48, 70}}}, {"minecraft:crimson_stairs", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_stem", {BLOCK_OPAQUE, {107, 51, 74}}}, +{"minecraft:crimson_stem", {BLOCK_OPAQUE, {112, 49, 70}}}, {"minecraft:crimson_trapdoor", {BLOCK_OPAQUE, {103, 50, 72}}}, {"minecraft:crimson_wall_sign", {0, {0, 0, 0}}}, {"minecraft:crying_obsidian", {BLOCK_OPAQUE, {32, 10, 60}}}, @@ -225,7 +225,7 @@ {"minecraft:dark_oak_fence", {BLOCK_OPAQUE, {66, 43, 20}}}, {"minecraft:dark_oak_fence_gate", {BLOCK_OPAQUE, {66, 43, 20}}}, {"minecraft:dark_oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {150, 150, 150}}}, -{"minecraft:dark_oak_log", {BLOCK_OPAQUE, {64, 42, 21}}}, +{"minecraft:dark_oak_log", {BLOCK_OPAQUE, {67, 45, 22}}}, {"minecraft:dark_oak_planks", {BLOCK_OPAQUE, {66, 43, 20}}}, {"minecraft:dark_oak_pressure_plate", {BLOCK_OPAQUE, {66, 43, 20}}}, {"minecraft:dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}}, @@ -325,7 +325,7 @@ {"minecraft:furnace", {BLOCK_OPAQUE, {110, 109, 109}}}, {"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {55, 42, 38}}}, {"minecraft:glass", {BLOCK_OPAQUE, {175, 213, 219}}}, -{"minecraft:glass_pane", {BLOCK_OPAQUE, {211, 239, 244}}}, +{"minecraft:glass_pane", {BLOCK_OPAQUE, {170, 210, 217}}}, {"minecraft:glow_item_frame", {0, {0, 0, 0}}}, {"minecraft:glow_lichen", {0, {0, 0, 0}}}, {"minecraft:glowstone", {BLOCK_OPAQUE, {171, 131, 84}}}, @@ -388,7 +388,7 @@ {"minecraft:infested_stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}}, {"minecraft:iron_bars", {BLOCK_OPAQUE, {136, 139, 135}}}, {"minecraft:iron_block", {BLOCK_OPAQUE, {220, 220, 220}}}, -{"minecraft:iron_door", {BLOCK_OPAQUE, {193, 192, 192}}}, +{"minecraft:iron_door", {BLOCK_OPAQUE, {194, 193, 193}}}, {"minecraft:iron_ore", {BLOCK_OPAQUE, {136, 129, 122}}}, {"minecraft:iron_trapdoor", {BLOCK_OPAQUE, {202, 202, 202}}}, {"minecraft:item_frame", {0, {0, 0, 0}}}, @@ -518,7 +518,7 @@ {"minecraft:netherrack", {BLOCK_OPAQUE, {97, 38, 38}}}, {"minecraft:note_block", {BLOCK_OPAQUE, {88, 58, 40}}}, {"minecraft:oak_button", {0, {0, 0, 0}}}, -{"minecraft:oak_door", {BLOCK_OPAQUE, {139, 110, 65}}}, +{"minecraft:oak_door", {BLOCK_OPAQUE, {140, 110, 66}}}, {"minecraft:oak_fence", {BLOCK_OPAQUE, {162, 130, 78}}}, {"minecraft:oak_fence_gate", {BLOCK_OPAQUE, {162, 130, 78}}}, {"minecraft:oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {144, 144, 144}}}, @@ -788,7 +788,7 @@ {"minecraft:stripped_crimson_hyphae", {BLOCK_OPAQUE, {137, 57, 90}}}, {"minecraft:stripped_crimson_stem", {BLOCK_OPAQUE, {121, 56, 82}}}, {"minecraft:stripped_dark_oak_log", {BLOCK_OPAQUE, {65, 44, 22}}}, -{"minecraft:stripped_dark_oak_wood", {BLOCK_OPAQUE, {96, 76, 49}}}, +{"minecraft:stripped_dark_oak_wood", {BLOCK_OPAQUE, {72, 56, 36}}}, {"minecraft:stripped_jungle_log", {BLOCK_OPAQUE, {165, 122, 81}}}, {"minecraft:stripped_jungle_wood", {BLOCK_OPAQUE, {171, 132, 84}}}, {"minecraft:stripped_oak_log", {BLOCK_OPAQUE, {160, 129, 77}}}, @@ -837,7 +837,7 @@ {"minecraft:warped_sign", {BLOCK_OPAQUE, {43, 104, 99}}}, {"minecraft:warped_slab", {BLOCK_OPAQUE, {43, 104, 99}}}, {"minecraft:warped_stairs", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_stem", {BLOCK_OPAQUE, {57, 103, 103}}}, +{"minecraft:warped_stem", {BLOCK_OPAQUE, {53, 109, 110}}}, {"minecraft:warped_trapdoor", {BLOCK_OPAQUE, {47, 119, 111}}}, {"minecraft:warped_wall_sign", {0, {0, 0, 0}}}, {"minecraft:warped_wart_block", {BLOCK_OPAQUE, {22, 119, 121}}}, From d18e004743f2db8c9d71e5f8f96810f535c6ae6d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Dec 2021 10:28:17 +0100 Subject: [PATCH 027/460] World: Section: fix biome palette size check We were accidentally checking the block type palette size. --- src/World/Section.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World/Section.cpp b/src/World/Section.cpp index 8d50bca..ffa2789 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -107,7 +107,7 @@ PaletteSection::PaletteSection( while ((1u << biomeBits) < biomePaletteData->size()) { biomeBits++; - if (bits > 6) + if (biomeBits > 6) throw std::invalid_argument("unsupported biome palette size"); } } From a2fe33ef1f7a3b405066a14c69cc1a340a763a7f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Dec 2021 12:15:31 +0100 Subject: [PATCH 028/460] World: Section: add support for Int tag section Y values For some reason, MC1.18 sometimes uses Int instead of Byte tags for section Y values after "optimize world". Add support for this (but still only accept values that fit in a int8_t). --- src/World/Section.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/World/Section.cpp b/src/World/Section.cpp index ffa2789..ba7b0c9 100644 --- a/src/World/Section.cpp +++ b/src/World/Section.cpp @@ -8,6 +8,7 @@ #include "Section.hpp" #include "../Resource/Biome.hpp" #include "../NBT/ByteTag.hpp" +#include "../NBT/IntTag.hpp" #include "../NBT/StringTag.hpp" #include @@ -17,7 +18,16 @@ namespace MinedMap { namespace World { Section::Section(const std::shared_ptr §ion) { - Y = int8_t(assertValue(section->get("Y"))->getValue()); + const std::shared_ptr YByteTag = section->get("Y"); + if (YByteTag) { + Y = int8_t(YByteTag->getValue()); + } else { + const std::shared_ptr YIntTag = assertValue(section->get("Y")); + int32_t value = YIntTag->getValue(); + if (int8_t(value) != value) + throw std::invalid_argument("unsupported section Y coordinate"); + Y = value; + } blockLight = section->get("BlockLight"); } From fac2e4c8da6fd0af2178318bb6adfea341bbcbaf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Dec 2021 12:18:18 +0100 Subject: [PATCH 029/460] World: Chunk: add support for unordered sections MC1.18 doesn't always store sections sorted by their Y value, possibly related to "optimize world". --- src/World/Chunk.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 136c3bf..b9d27c5 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -52,17 +52,35 @@ Chunk::Chunk(const ChunkData *data) { auto dataVersionTag = data->getRoot()->get("DataVersion"); uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0; + std::vector> tmpSections; + section_idx_t minY = std::numeric_limits::max(); + section_idx_t maxY = std::numeric_limits::min(); + for (auto &sTag : *sectionsTag) { auto s = std::dynamic_pointer_cast(sTag); std::unique_ptr
section = Section::makeSection(s, dataVersion); section_idx_t Y = section->getY(); - if (sections.empty()) - sectionOffset = Y; + if (Y < minY) + minY = Y; + if (Y > maxY) + maxY = Y; + tmpSections.push_back(std::move(section)); + } + + if (tmpSections.empty()) + return; + + assertValue(minY <= maxY); + sectionOffset = minY; + sections.resize(maxY - minY + 1); + + for (auto §ion : tmpSections) { + section_idx_t Y = section->getY(); Y -= sectionOffset; - assertValue(Y >= 0 && size_t(Y) >= sections.size()); - sections.resize(Y); - sections.push_back(std::move(section)); + assertValue(Y >= 0 && size_t(Y) < sections.size()); + assertValue(!sections[Y]); + sections[Y] = std::move(section); } } From 37340926f4a2a3f6cd346f78fa6f9c91e5c87775 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 19 Dec 2021 23:10:42 +0100 Subject: [PATCH 030/460] MinedMap: fix warning for unused fscanf result --- src/MinedMap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index 6c55851..e4993a0 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -133,7 +133,9 @@ static int64_t readStamp(const std::string &filename) { std::FILE *f = std::fopen((filename + ".stamp").c_str(), "r"); if (f) { - std::fscanf(f, "%" SCNd64, &v); + if (std::fscanf(f, "%" SCNd64, &v) != 1) { + // Ignore errors + } std::fclose(f); } From 00b93c507d5d7d60808ca598be76fe535da28e69 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 19 Dec 2021 23:12:25 +0100 Subject: [PATCH 031/460] ci: add GitHub actions for Linux and Windows builds We build a "static" binary for Windows now to avoid distributing the dependencies as DLLs. --- .github/toolchains/x86_64-linux-gnu.cmake | 0 .github/toolchains/x86_64-w64-mingw32.cmake | 22 +++++ .../x86_64-w64-mingw32/FindPkgConfig.cmake | 5 ++ .github/workflows/MinedMap.yml | 85 +++++++++++++++++++ CMakePresets.json | 39 +++++++++ 5 files changed, 151 insertions(+) create mode 100644 .github/toolchains/x86_64-linux-gnu.cmake create mode 100644 .github/toolchains/x86_64-w64-mingw32.cmake create mode 100644 .github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake create mode 100644 .github/workflows/MinedMap.yml create mode 100644 CMakePresets.json diff --git a/.github/toolchains/x86_64-linux-gnu.cmake b/.github/toolchains/x86_64-linux-gnu.cmake new file mode 100644 index 0000000..e69de29 diff --git a/.github/toolchains/x86_64-w64-mingw32.cmake b/.github/toolchains/x86_64-w64-mingw32.cmake new file mode 100644 index 0000000..53256c1 --- /dev/null +++ b/.github/toolchains/x86_64-w64-mingw32.cmake @@ -0,0 +1,22 @@ +set(TARGET x86_64-w64-mingw32) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.github/toolchains/${TARGET}) + +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSROOT /usr/${TARGET}) + +set(CMAKE_C_COMPILER ${TARGET}-gcc) +set(CMAKE_CXX_COMPILER ${TARGET}-g++) + +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share/pkgconfig) +set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR}) + +set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) + +set(CMAKE_EXE_LINKER_FLAGS "-static") + + diff --git a/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake b/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake new file mode 100644 index 0000000..79166ed --- /dev/null +++ b/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake @@ -0,0 +1,5 @@ +# Hack: The toolchain file is evaluated too early to set the library suffixes, so we use a wrapper +# around FindPkgConfig set it right before we search for libraries. +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + +include(${CMAKE_ROOT}/Modules/FindPkgConfig.cmake) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml new file mode 100644 index 0000000..7350a3e --- /dev/null +++ b/.github/workflows/MinedMap.yml @@ -0,0 +1,85 @@ +name: 'MinedMap' +on: ['push', 'pull_request', 'workflow_dispatch'] + +jobs: + build: + name: 'Build MinedMap (${{ matrix.host }})' + runs-on: 'ubuntu-20.04' + strategy: + fail-fast: false + matrix: + host: + - 'x86_64-linux-gnu' + - 'x86_64-w64-mingw32' + include: + - host: 'x86_64-linux-gnu' + label: 'x86_64-linux-gnu' + packages: ['g++', 'libpng-dev'] + prefix: '/usr' + build_libpng: false + - host: 'x86_64-w64-mingw32' + label: 'Win64' + packages: ['g++-mingw-w64-x86-64', 'libz-mingw-w64-dev'] + prefix: '/usr/x86_64-w64-mingw32' + build_libpng: true + + env: + CMAKE_TOOLCHAIN_FILE: '${{ github.workspace }}/.github/toolchains/${{ matrix.host }}.cmake' + + steps: + - name: 'Checkout' + uses: 'actions/checkout@v2' + + - name: 'Get version' + id: 'tag' + run: | + set -o pipefail + git fetch --prune --unshallow + git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' + + - name: 'Dependencies (apt)' + run: | + sudo apt-get -y update + sudo apt-get -y install ninja-build ${{ join(matrix.packages, ' ') }} + sudo apt-get -y clean + + - name: 'Dependencies (libpng)' + if: '${{ matrix.build_libpng }}' + run: | + pkgver=1.6.37 + pkghash=505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca + + mkdir -p build/libpng + cd build/libpng + wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pkgver.tar.xz + echo "$pkghash libpng-$pkgver.tar.xz" | sha256sum -c - + tar xf libpng-$pkgver.tar.xz + cd libpng-$pkgver + ./configure \ + --prefix=${{ matrix.prefix }} \ + --host=${{ matrix.host }} \ + --disable-shared + make -j$(nproc) + sudo make install + sudo rm ${{ matrix.prefix }}/lib/libpng*.la + + - name: 'Build' + uses: lukka/run-cmake@v10 + with: + configurePreset: 'ninja' + buildPreset: 'ninja-release' + + - name: 'Install' + run: | + export DESTDIR="$(pwd)/build/install" + ninja -C builds/ninja -f build-RelWithDebInfo.ninja install/strip + + pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' + mkdir -p "$pkgdir" + cp "$DESTDIR/usr/local/bin"/* "$pkgdir"/ + + - name: 'Archive' + uses: 'actions/upload-artifact@v2' + with: + name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' + path: 'build/pkg' diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..bc371b3 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,39 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 7, + "patch": 0 + }, + "configurePresets": [ + { + "name": "ninja", + "displayName": "Ninja", + "description": "Generate Ninja project files", + "binaryDir": "${sourceDir}/builds/${presetName}", + "generator": "Ninja Multi-Config", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "$env{CMAKE_TOOLCHAIN_FILE}" + } + } + } + ], + "buildPresets": [ + { + "name": "ninja-debug", + "configurePreset": "ninja", + "displayName": "Build ninja-debug", + "description": "Build ninja Debug configuration", + "configuration": "Debug" + }, + { + "name": "ninja-release", + "configurePreset": "ninja", + "displayName": "Build ninja-release", + "description": "Build ninja Release configuration", + "configuration": "RelWithDebInfo" + } + ] +} From 7c13d850b7bafd5064ec9951f8af93186e6fc518 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 19 Dec 2021 23:19:56 +0100 Subject: [PATCH 032/460] ci: add viewer artifact --- .github/workflows/MinedMap.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 7350a3e..5d6d655 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -83,3 +83,30 @@ jobs: with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' path: 'build/pkg' + + viewer: + name: 'Package viewer' + runs-on: 'ubuntu-20.04' + + steps: + - name: 'Checkout' + uses: 'actions/checkout@v2' + + - name: 'Get version' + id: 'tag' + run: | + set -o pipefail + git fetch --prune --unshallow + git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' + + - name: 'Install' + run: | + pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-viewer' + mkdir -p "$pkgdir" + cp -r viewer/* "$pkgdir"/ + + - name: 'Archive' + uses: 'actions/upload-artifact@v2' + with: + name: 'MinedMap-${{ steps.tag.outputs.tag }}-viewer' + path: 'build/pkg' From 056cee8585bb1eb5294a45076a1d70b29892e0b4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 21 Dec 2021 23:35:00 +0100 Subject: [PATCH 033/460] build: replace FindPkgConfig hack with BUILD_STATIC variable set by CI toolchain file --- .github/toolchains/x86_64-w64-mingw32.cmake | 6 +----- .../toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake | 5 ----- CMakeLists.txt | 10 +++++++++- 3 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 .github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake diff --git a/.github/toolchains/x86_64-w64-mingw32.cmake b/.github/toolchains/x86_64-w64-mingw32.cmake index 53256c1..08e3281 100644 --- a/.github/toolchains/x86_64-w64-mingw32.cmake +++ b/.github/toolchains/x86_64-w64-mingw32.cmake @@ -1,6 +1,6 @@ set(TARGET x86_64-w64-mingw32) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.github/toolchains/${TARGET}) +set(BUILD_STATIC ON) set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSROOT /usr/${TARGET}) @@ -16,7 +16,3 @@ set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR}) set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) - -set(CMAKE_EXE_LINKER_FLAGS "-static") - - diff --git a/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake b/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake deleted file mode 100644 index 79166ed..0000000 --- a/.github/toolchains/x86_64-w64-mingw32/FindPkgConfig.cmake +++ /dev/null @@ -1,5 +0,0 @@ -# Hack: The toolchain file is evaluated too early to set the library suffixes, so we use a wrapper -# around FindPkgConfig set it right before we search for libraries. -set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - -include(${CMAKE_ROOT}/Modules/FindPkgConfig.cmake) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70385e8..996ec67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,14 @@ -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.13) project(MINEDMAP CXX) +# May not work with all toolchains, added for the Windows CI build +option(BUILD_STATIC "Create a statically linked MinedMap executable") + +if(BUILD_STATIC) + list(REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".dll.a") + add_link_options("-static") +endif() + find_package(PkgConfig REQUIRED) pkg_check_modules(ZLIB REQUIRED IMPORTED_TARGET zlib) From 429e449c64f7bdd50d200e2d76a53a393ac8d6cd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 21 Dec 2021 23:55:27 +0100 Subject: [PATCH 034/460] ci: add Win32 build --- .github/toolchains/common-w64-mingw32.cmake | 16 ++++++++++++++++ .github/toolchains/i686-w64-mingw32.cmake | 2 ++ .github/toolchains/x86_64-w64-mingw32.cmake | 18 +----------------- .github/workflows/MinedMap.yml | 5 +++++ 4 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 .github/toolchains/common-w64-mingw32.cmake create mode 100644 .github/toolchains/i686-w64-mingw32.cmake diff --git a/.github/toolchains/common-w64-mingw32.cmake b/.github/toolchains/common-w64-mingw32.cmake new file mode 100644 index 0000000..7fcee75 --- /dev/null +++ b/.github/toolchains/common-w64-mingw32.cmake @@ -0,0 +1,16 @@ +set(BUILD_STATIC ON) + +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSROOT /usr/${TARGET}) + +set(CMAKE_C_COMPILER ${TARGET}-gcc) +set(CMAKE_CXX_COMPILER ${TARGET}-g++) + +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share/pkgconfig) +set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR}) + +set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) diff --git a/.github/toolchains/i686-w64-mingw32.cmake b/.github/toolchains/i686-w64-mingw32.cmake new file mode 100644 index 0000000..7d1612a --- /dev/null +++ b/.github/toolchains/i686-w64-mingw32.cmake @@ -0,0 +1,2 @@ +set(TARGET i686-w64-mingw32) +include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake) diff --git a/.github/toolchains/x86_64-w64-mingw32.cmake b/.github/toolchains/x86_64-w64-mingw32.cmake index 08e3281..cab56f4 100644 --- a/.github/toolchains/x86_64-w64-mingw32.cmake +++ b/.github/toolchains/x86_64-w64-mingw32.cmake @@ -1,18 +1,2 @@ set(TARGET x86_64-w64-mingw32) - -set(BUILD_STATIC ON) - -set(CMAKE_SYSTEM_NAME Windows) -set(CMAKE_SYSROOT /usr/${TARGET}) - -set(CMAKE_C_COMPILER ${TARGET}-gcc) -set(CMAKE_CXX_COMPILER ${TARGET}-g++) - -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - -set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share/pkgconfig) -set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR}) - -set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) +include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 5d6d655..dcba86a 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -22,6 +22,11 @@ jobs: packages: ['g++-mingw-w64-x86-64', 'libz-mingw-w64-dev'] prefix: '/usr/x86_64-w64-mingw32' build_libpng: true + - host: 'i686-w64-mingw32' + label: 'Win32' + packages: ['g++-mingw-w64-i686', 'libz-mingw-w64-dev'] + prefix: '/usr/i686-w64-mingw32' + build_libpng: true env: CMAKE_TOOLCHAIN_FILE: '${{ github.workspace }}/.github/toolchains/${{ matrix.host }}.cmake' From 3160b59cdd3665c46f61d38dc868265fcb837c03 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 22 Dec 2021 16:08:56 +0100 Subject: [PATCH 035/460] README.md: add 1.18 support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fb8452..a04462a 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.17 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.18 (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 * Incremental updates: only recreate map tiles for regions that have changed From fbef307c90a96b39dde1f36f2ebe1f764c18bdd2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 9 Feb 2022 21:26:12 +0100 Subject: [PATCH 036/460] UniqueCPtr: add doc comment Explain what a UniqueCPtr is. --- src/UniqueCPtr.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/UniqueCPtr.hpp b/src/UniqueCPtr.hpp index 647f7e1..743a712 100644 --- a/src/UniqueCPtr.hpp +++ b/src/UniqueCPtr.hpp @@ -10,7 +10,9 @@ #include #include - +// UniqueCPtr is a wrapper around std::unique_ptr using std::free as its deallocator +// +// This allows to use it to manage memory allocated by C APIs (malloc, realloc, ...) template class UniqueCPtr : public std::unique_ptr { public: UniqueCPtr() : std::unique_ptr(nullptr, std::free) {} From 7bba6d08637105a65503708f0a752aa4b866c46b Mon Sep 17 00:00:00 2001 From: Bruno Saad Date: Tue, 7 Jun 2022 16:48:43 +0000 Subject: [PATCH 037/460] Adding new blocks for 1.19 --- resource/blocks.json | 83 ++++++++++++++++++++++++++++++++++ src/Resource/BlockType.inc.cpp | 45 ++++++++++++++++-- 2 files changed, 123 insertions(+), 5 deletions(-) diff --git a/resource/blocks.json b/resource/blocks.json index 78c0d4c..cfb908f 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -599,6 +599,7 @@ "texture": "flowering_azalea_top" }, "flowering_azalea_leaves": {}, + "frogspawn": {}, "frosted_ice": { "texture": "frosted_ice_0" }, @@ -889,6 +890,44 @@ "magma_block": { "texture": "magma" }, + "mangrove_button": null, + "mangrove_door": { + "texture": "mangrove_door_top" + }, + "mangrove_fence": { + "texture": "mangrove_planks" + }, + "mangrove_fence_gate": { + "texture": "mangrove_planks" + }, + "mangrove_leaves": { + "foliage": true + }, + "mangrove_log": { + "texture": "mangrove_log_top" + }, + "mangrove_planks": {}, + "mangrove_pressure_plate": { + "texture": "mangrove_planks" + }, + "mangrove_propagule": {}, + "mangrove_roots": { + "texture": "mangrove_roots_top" + }, + "mangrove_sign": { + "texture": "mangrove_planks" + }, + "mangrove_slab": { + "texture": "mangrove_planks" + }, + "mangrove_stairs": { + "texture": "mangrove_planks" + }, + "mangrove_trapdoor": {}, + "mangrove_wall_sign": null, + "mangrove_wood": { + "texture": "mangrove_log" + }, "medium_amethyst_bud": null, "melon": { "texture": "melon_top" @@ -921,6 +960,20 @@ }, "mossy_stone_bricks": {}, "moving_piston": null, + "mud": {}, + "mud_brick_slab": { + "texture": "mud_bricks" + }, + "mud_brick_stairs": { + "texture": "mud_bricks" + }, + "mud_brick_wall": { + "texture": "mud_bricks" + }, + "mud_bricks": {}, + "muddy_mangrove_roots": { + "texture": "muddy_mangrove_roots_top" + }, "mushroom_stem": {}, "mycelium": { "texture": "mycelium_top" @@ -988,6 +1041,9 @@ "texture": "observer_top" }, "obsidian": {}, + "ochre_froglight": { + "texture": "ochre_froglight_top" + }, "orange_banner": null, "orange_bed": null, "orange_candle": null, @@ -1019,6 +1075,10 @@ "texture": "oxidized_cut_copper" }, "packed_ice": {}, + "packed_mud": {}, + "pearlescent_froglight": { + "texture": "pearlescent_froglight_top" + }, "peony": { "texture": "peony_top" }, @@ -1180,6 +1240,9 @@ "potted_lily_of_the_valley": { "texture": "lily_of_the_valley" }, + "potted_mangrove_propagule": { + "texture": "mangrove_propagule" + }, "potted_oak_sapling": { "texture": "oak_sapling" }, @@ -1341,6 +1404,9 @@ "redstone_wire": { "texture": "redstone_block" }, + "reinforced_deepslate": { + "texture": "reinforced_deepslate_top" + }, "repeater": {}, "repeating_command_block": { "texture": "repeating_command_block_front" @@ -1368,9 +1434,17 @@ "scaffolding": { "texture": "scaffolding_top" }, + "sculk": {}, + "sculk_catalyst": { + "texture": "sculk_catalyst_top" + }, "sculk_sensor": { "texture": "sculk_sensor_top" }, + "sculk_shrieker": { + "texture": "sculk_shrieker_top" + }, + "sculk_vein": {}, "sea_lantern": {}, "sea_pickle": {}, "seagrass": null, @@ -1532,6 +1606,12 @@ "stripped_jungle_wood": { "texture": "stripped_jungle_log" }, + "stripped_mangrove_log": { + "texture": "stripped_mangrove_log_top" + }, + "stripped_mangrove_wood": { + "texture": "stripped_mangrove_log" + }, "stripped_oak_log": { "texture": "stripped_oak_log_top" }, @@ -1588,6 +1668,9 @@ "turtle_egg": {}, "twisting_vines": {}, "twisting_vines_plant": {}, + "verdant_froglight": { + "texture": "verdant_froglight_top" + }, "vine": { "grass": true }, diff --git a/src/Resource/BlockType.inc.cpp b/src/Resource/BlockType.inc.cpp index 9a4ff17..bc6c087 100644 --- a/src/Resource/BlockType.inc.cpp +++ b/src/Resource/BlockType.inc.cpp @@ -98,7 +98,7 @@ {"minecraft:brain_coral_block", {BLOCK_OPAQUE, {207, 91, 159}}}, {"minecraft:brain_coral_fan", {0, {0, 0, 0}}}, {"minecraft:brain_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:brewing_stand", {BLOCK_OPAQUE, {123, 101, 81}}}, +{"minecraft:brewing_stand", {BLOCK_OPAQUE, {122, 100, 80}}}, {"minecraft:brick_slab", {BLOCK_OPAQUE, {150, 97, 83}}}, {"minecraft:brick_stairs", {BLOCK_OPAQUE, {150, 97, 83}}}, {"minecraft:brick_wall", {BLOCK_OPAQUE, {150, 97, 83}}}, @@ -164,7 +164,7 @@ {"minecraft:cobblestone_stairs", {BLOCK_OPAQUE, {127, 127, 127}}}, {"minecraft:cobblestone_wall", {BLOCK_OPAQUE, {127, 127, 127}}}, {"minecraft:cobweb", {BLOCK_OPAQUE, {228, 233, 234}}}, -{"minecraft:cocoa", {BLOCK_OPAQUE, {156, 94, 43}}}, +{"minecraft:cocoa", {BLOCK_OPAQUE, {154, 91, 40}}}, {"minecraft:command_block", {BLOCK_OPAQUE, {181, 136, 108}}}, {"minecraft:comparator", {BLOCK_OPAQUE, {166, 161, 159}}}, {"minecraft:composter", {BLOCK_OPAQUE, {88, 61, 23}}}, @@ -321,6 +321,7 @@ {"minecraft:flower_pot", {BLOCK_OPAQUE, {124, 68, 53}}}, {"minecraft:flowering_azalea", {BLOCK_OPAQUE, {112, 121, 64}}}, {"minecraft:flowering_azalea_leaves", {BLOCK_OPAQUE, {99, 111, 60}}}, +{"minecraft:frogspawn", {BLOCK_OPAQUE, {105, 90, 82}}}, {"minecraft:frosted_ice", {BLOCK_OPAQUE, {140, 181, 252}}}, {"minecraft:furnace", {BLOCK_OPAQUE, {110, 109, 109}}}, {"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {55, 42, 38}}}, @@ -487,6 +488,22 @@ {"minecraft:magenta_wall_banner", {0, {0, 0, 0}}}, {"minecraft:magenta_wool", {BLOCK_OPAQUE, {189, 68, 179}}}, {"minecraft:magma_block", {BLOCK_OPAQUE, {142, 63, 31}}}, +{"minecraft:mangrove_button", {0, {0, 0, 0}}}, +{"minecraft:mangrove_door", {BLOCK_OPAQUE, {112, 48, 46}}}, +{"minecraft:mangrove_fence", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_fence_gate", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {129, 128, 128}}}, +{"minecraft:mangrove_log", {BLOCK_OPAQUE, {102, 48, 42}}}, +{"minecraft:mangrove_planks", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_pressure_plate", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}}, +{"minecraft:mangrove_roots", {BLOCK_OPAQUE, {74, 59, 38}}}, +{"minecraft:mangrove_sign", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_slab", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_stairs", {BLOCK_OPAQUE, {117, 54, 48}}}, +{"minecraft:mangrove_trapdoor", {BLOCK_OPAQUE, {110, 46, 42}}}, +{"minecraft:mangrove_wall_sign", {0, {0, 0, 0}}}, +{"minecraft:mangrove_wood", {BLOCK_OPAQUE, {83, 66, 41}}}, {"minecraft:medium_amethyst_bud", {0, {0, 0, 0}}}, {"minecraft:melon", {BLOCK_OPAQUE, {111, 144, 30}}}, {"minecraft:melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {153, 153, 153}}}, @@ -501,6 +518,12 @@ {"minecraft:mossy_stone_brick_wall", {BLOCK_OPAQUE, {115, 121, 105}}}, {"minecraft:mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}}, {"minecraft:moving_piston", {0, {0, 0, 0}}}, +{"minecraft:mud", {BLOCK_OPAQUE, {60, 57, 60}}}, +{"minecraft:mud_brick_slab", {BLOCK_OPAQUE, {137, 103, 79}}}, +{"minecraft:mud_brick_stairs", {BLOCK_OPAQUE, {137, 103, 79}}}, +{"minecraft:mud_brick_wall", {BLOCK_OPAQUE, {137, 103, 79}}}, +{"minecraft:mud_bricks", {BLOCK_OPAQUE, {137, 103, 79}}}, +{"minecraft:muddy_mangrove_roots", {BLOCK_OPAQUE, {70, 58, 45}}}, {"minecraft:mushroom_stem", {BLOCK_OPAQUE, {203, 196, 185}}}, {"minecraft:mycelium", {BLOCK_OPAQUE, {111, 98, 101}}}, {"minecraft:nether_brick_fence", {BLOCK_OPAQUE, {44, 21, 26}}}, @@ -534,6 +557,7 @@ {"minecraft:oak_wood", {BLOCK_OPAQUE, {109, 85, 50}}}, {"minecraft:observer", {BLOCK_OPAQUE, {98, 98, 98}}}, {"minecraft:obsidian", {BLOCK_OPAQUE, {15, 10, 24}}}, +{"minecraft:ochre_froglight", {BLOCK_OPAQUE, {250, 245, 206}}}, {"minecraft:orange_banner", {0, {0, 0, 0}}}, {"minecraft:orange_bed", {0, {0, 0, 0}}}, {"minecraft:orange_candle", {0, {0, 0, 0}}}, @@ -555,6 +579,8 @@ {"minecraft:oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}}, {"minecraft:oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}}, {"minecraft:packed_ice", {BLOCK_OPAQUE, {141, 180, 250}}}, +{"minecraft:packed_mud", {BLOCK_OPAQUE, {142, 106, 79}}}, +{"minecraft:pearlescent_froglight", {BLOCK_OPAQUE, {245, 240, 239}}}, {"minecraft:peony", {BLOCK_OPAQUE, {129, 126, 139}}}, {"minecraft:petrified_oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}}, {"minecraft:pink_banner", {0, {0, 0, 0}}}, @@ -572,8 +598,8 @@ {"minecraft:pink_tulip", {0, {0, 0, 0}}}, {"minecraft:pink_wall_banner", {0, {0, 0, 0}}}, {"minecraft:pink_wool", {BLOCK_OPAQUE, {237, 141, 172}}}, -{"minecraft:piston", {BLOCK_OPAQUE, {110, 104, 96}}}, -{"minecraft:piston_head", {BLOCK_OPAQUE, {154, 127, 87}}}, +{"minecraft:piston", {BLOCK_OPAQUE, {109, 104, 96}}}, +{"minecraft:piston_head", {BLOCK_OPAQUE, {153, 127, 85}}}, {"minecraft:player_head", {0, {0, 0, 0}}}, {"minecraft:player_wall_head", {0, {0, 0, 0}}}, {"minecraft:podzol", {BLOCK_OPAQUE, {91, 63, 24}}}, @@ -623,6 +649,7 @@ {"minecraft:potted_flowering_azalea_bush", {BLOCK_OPAQUE, {112, 121, 64}}}, {"minecraft:potted_jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}}, {"minecraft:potted_lily_of_the_valley", {BLOCK_OPAQUE, {123, 174, 95}}}, +{"minecraft:potted_mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}}, {"minecraft:potted_oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}}, {"minecraft:potted_orange_tulip", {BLOCK_OPAQUE, {93, 142, 30}}}, {"minecraft:potted_oxeye_daisy", {BLOCK_OPAQUE, {179, 202, 143}}}, @@ -706,6 +733,7 @@ {"minecraft:redstone_torch", {0, {0, 0, 0}}}, {"minecraft:redstone_wall_torch", {0, {0, 0, 0}}}, {"minecraft:redstone_wire", {BLOCK_OPAQUE, {175, 24, 5}}}, +{"minecraft:reinforced_deepslate", {BLOCK_OPAQUE, {80, 82, 78}}}, {"minecraft:repeater", {BLOCK_OPAQUE, {160, 157, 156}}}, {"minecraft:repeating_command_block", {BLOCK_OPAQUE, {129, 111, 176}}}, {"minecraft:respawn_anchor", {BLOCK_OPAQUE, {75, 26, 144}}}, @@ -717,7 +745,11 @@ {"minecraft:sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:sandstone_wall", {BLOCK_OPAQUE, {223, 214, 170}}}, {"minecraft:scaffolding", {BLOCK_OPAQUE, {174, 134, 80}}}, +{"minecraft:sculk", {BLOCK_OPAQUE, {12, 29, 36}}}, +{"minecraft:sculk_catalyst", {BLOCK_OPAQUE, {15, 31, 38}}}, {"minecraft:sculk_sensor", {BLOCK_OPAQUE, {7, 70, 84}}}, +{"minecraft:sculk_shrieker", {BLOCK_OPAQUE, {198, 205, 169}}}, +{"minecraft:sculk_vein", {BLOCK_OPAQUE, {7, 48, 57}}}, {"minecraft:sea_lantern", {BLOCK_OPAQUE, {172, 199, 190}}}, {"minecraft:sea_pickle", {BLOCK_OPAQUE, {90, 97, 39}}}, {"minecraft:seagrass", {0, {0, 0, 0}}}, @@ -770,7 +802,7 @@ {"minecraft:spruce_trapdoor", {BLOCK_OPAQUE, {103, 79, 47}}}, {"minecraft:spruce_wall_sign", {0, {0, 0, 0}}}, {"minecraft:spruce_wood", {BLOCK_OPAQUE, {58, 37, 16}}}, -{"minecraft:sticky_piston", {BLOCK_OPAQUE, {110, 104, 96}}}, +{"minecraft:sticky_piston", {BLOCK_OPAQUE, {109, 104, 96}}}, {"minecraft:stone", {BLOCK_OPAQUE, {125, 125, 125}}}, {"minecraft:stone_brick_slab", {BLOCK_OPAQUE, {122, 121, 122}}}, {"minecraft:stone_brick_stairs", {BLOCK_OPAQUE, {122, 121, 122}}}, @@ -791,6 +823,8 @@ {"minecraft:stripped_dark_oak_wood", {BLOCK_OPAQUE, {72, 56, 36}}}, {"minecraft:stripped_jungle_log", {BLOCK_OPAQUE, {165, 122, 81}}}, {"minecraft:stripped_jungle_wood", {BLOCK_OPAQUE, {171, 132, 84}}}, +{"minecraft:stripped_mangrove_log", {BLOCK_OPAQUE, {109, 43, 43}}}, +{"minecraft:stripped_mangrove_wood", {BLOCK_OPAQUE, {119, 54, 47}}}, {"minecraft:stripped_oak_log", {BLOCK_OPAQUE, {160, 129, 77}}}, {"minecraft:stripped_oak_wood", {BLOCK_OPAQUE, {177, 144, 86}}}, {"minecraft:stripped_spruce_log", {BLOCK_OPAQUE, {105, 80, 46}}}, @@ -820,6 +854,7 @@ {"minecraft:turtle_egg", {BLOCK_OPAQUE, {228, 226, 191}}}, {"minecraft:twisting_vines", {BLOCK_OPAQUE, {20, 143, 124}}}, {"minecraft:twisting_vines_plant", {BLOCK_OPAQUE, {20, 135, 122}}}, +{"minecraft:verdant_froglight", {BLOCK_OPAQUE, {229, 244, 228}}}, {"minecraft:vine", {BLOCK_OPAQUE|BLOCK_GRASS, {116, 116, 116}}}, {"minecraft:void_air", {0, {0, 0, 0}}}, {"minecraft:wall_sign", {0, {0, 0, 0}}}, From 74bd6205b07e52d6fae3c3ff6b571888f44b895f Mon Sep 17 00:00:00 2001 From: Bruno Saad Date: Tue, 7 Jun 2022 22:43:02 +0000 Subject: [PATCH 038/460] updates the gitignore to include common used directories in the documentation --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5e3deeb..a8d69d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *~ /viewer/data +/resource/data +/resource/colors.json .idea/ cmake-build-debug/ From 600a20cde6846557e5865de4abc5416dc8997c46 Mon Sep 17 00:00:00 2001 From: Andrew Cox Date: Fri, 1 Jul 2022 14:27:58 -0700 Subject: [PATCH 039/460] Update to compile on Mac OS (#26) --- src/MinedMap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp index e4993a0..7103d89 100644 --- a/src/MinedMap.cpp +++ b/src/MinedMap.cpp @@ -192,8 +192,10 @@ static int64_t getModTime(const std::string &file) { return INT64_MIN; } -#ifdef _WIN32 +#if defined(_WIN32) return (int64_t)s.st_mtime * 1000000; +#elif defined(__APPLE__) + return (int64_t)s.st_mtimespec.tv_sec * 1000000 + s.st_mtimespec.tv_nsec / 1000; #else return (int64_t)s.st_mtim.tv_sec * 1000000 + s.st_mtim.tv_nsec / 1000; #endif From 6125b1b0279469fbf253ed8ff6ec89f4050e897e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Oct 2022 11:11:09 +0200 Subject: [PATCH 040/460] README.md: add 1.19 support --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a04462a..708fe3d 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.18 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.19 (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 * Incremental updates: only recreate map tiles for regions that have changed From 6605483b4dd46f71d657634cba8a7ff7b964df55 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Oct 2022 12:24:48 +0200 Subject: [PATCH 041/460] workflows: force tag update to get version When building from a tag, Github will create a lightweight tag in place of the proper one when fetching, breaking `git describe`. Force an update of all tags to avoid this. --- .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 dcba86a..bf157d6 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -39,7 +39,7 @@ jobs: id: 'tag' run: | set -o pipefail - git fetch --prune --unshallow + git fetch --prune --unshallow --tags -f git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' - name: 'Dependencies (apt)' @@ -101,7 +101,7 @@ jobs: id: 'tag' run: | set -o pipefail - git fetch --prune --unshallow + git fetch --prune --unshallow --tags -f git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' - name: 'Install' From c43c185d9bf3f4c5f6c1c64bc8cea5019d455997 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Oct 2022 12:44:05 +0200 Subject: [PATCH 042/460] workflows: update checkout/upload actions --- .github/workflows/MinedMap.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index bf157d6..f1c761a 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -33,7 +33,7 @@ jobs: steps: - name: 'Checkout' - uses: 'actions/checkout@v2' + uses: 'actions/checkout@v3' - name: 'Get version' id: 'tag' @@ -84,7 +84,7 @@ jobs: cp "$DESTDIR/usr/local/bin"/* "$pkgdir"/ - name: 'Archive' - uses: 'actions/upload-artifact@v2' + uses: 'actions/upload-artifact@v3' with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' path: 'build/pkg' @@ -95,7 +95,7 @@ jobs: steps: - name: 'Checkout' - uses: 'actions/checkout@v2' + uses: 'actions/checkout@v3' - name: 'Get version' id: 'tag' @@ -111,7 +111,7 @@ jobs: cp -r viewer/* "$pkgdir"/ - name: 'Archive' - uses: 'actions/upload-artifact@v2' + uses: 'actions/upload-artifact@v3' with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-viewer' path: 'build/pkg' From 4ce08a7d5d01f0013f21b2fd2253a63bea119aa9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Oct 2022 12:49:13 +0200 Subject: [PATCH 043/460] workflows: replace deprecated set-output --- .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 f1c761a..1318eab 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -40,7 +40,7 @@ jobs: run: | set -o pipefail git fetch --prune --unshallow --tags -f - git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' + echo "tag=$(git describe --abbrev=7 --match='v*' | sed 's/^v//')" >> $GITHUB_OUTPUT - name: 'Dependencies (apt)' run: | @@ -102,7 +102,7 @@ jobs: run: | set -o pipefail git fetch --prune --unshallow --tags -f - git describe --abbrev=7 --match='v*' | sed 's/^v/::set-output name=tag::/' + echo "tag=$(git describe --abbrev=7 --match='v*' | sed 's/^v//')" >> $GITHUB_OUTPUT - name: 'Install' run: | From c7e04649ff7cf625d2fb9ef3f85765c69a7cb906 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 16 Oct 2022 13:14:31 +0200 Subject: [PATCH 044/460] Resource: Biome: add 1.19 biomes Add the new biome temperature and rainfall values, as found in decompiled Minecraft code: - Deep Dark uses the same the values as plains - Mangrove Swamp has the same temperature/rainfall as regular Swamp, but a different water color --- src/Resource/Biome.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp index d871ad5..1ca2114 100644 --- a/src/Resource/Biome.cpp +++ b/src/Resource/Biome.cpp @@ -116,7 +116,8 @@ public: }; -/* Values from https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp */ +/* Values from https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp or + * extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn */ static const Biome BiomeDefault(0.5f, 0.5f); static const Biome BiomePlains(0.8f, 0.4f); @@ -149,6 +150,7 @@ static const Biome BiomeGrove(-0.2f, 0.8f); static const Biome BiomeJaggedPeaks(-0.7f, 0.9f); static const Biome BiomeStonyPeaks(1.0f, 0.3f); static const Biome BiomeSnowySlopes(-0.3f, 0.9f); +static const SwampBiome BiomeMangroveSwamp(0.8f, 0.9f, {0.227f, 0.478f, 0.416f}); const Biome *const Biome::Default = &BiomeDefault; @@ -213,7 +215,7 @@ const Biome *const Biome::Biomes[256] = { /* 53 */ &BiomeJaggedPeaks, /* MinedMap assignment */ /* 54 */ &BiomeStonyPeaks, /* MinedMap assignment */ /* 55 */ &BiomeSnowySlopes, /* MinedMap assignment */ - /* 56 */ nullptr, + /* 56 */ &BiomeMangroveSwamp, /* MinedMap assignment */ /* 57 */ nullptr, /* 58 */ nullptr, /* 59 */ nullptr, @@ -352,6 +354,7 @@ const std::unordered_map Biome::Names = { { "minecraft:dark_forest", 29 }, { "minecraft:dark_forest_hills", 157 }, /* 1.18: Merged into dark_forest */ { "minecraft:deep_cold_ocean", 49 }, + { "minecraft:deep_dark", 1 }, { "minecraft:deep_frozen_ocean", 50 }, { "minecraft:deep_lukewarm_ocean", 48 }, { "minecraft:deep_ocean", 24 }, @@ -383,6 +386,7 @@ const std::unordered_map Biome::Names = { { "minecraft:jungle_hills", 22 }, /* 1.18: Merged into jungle */ { "minecraft:lukewarm_ocean", 45 }, { "minecraft:lush_caves", 175 }, + { "minecraft:mangrove_swamp", 56 }, { "minecraft:meadow", 51 }, /* 1.18: New */ { "minecraft:modified_badlands_plateau", 167 }, /* 1.18: Merged into badlands */ { "minecraft:modified_gravelly_mountains", 162 }, /* 1.18: Merged into gravelly_mountains */ From 4b83f6376f39b34e61e291faee873a7cb444b72b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 24 Jan 2023 18:46:48 +0100 Subject: [PATCH 045/460] Remove C++ implementation --- .github/toolchains/common-w64-mingw32.cmake | 16 - .github/toolchains/i686-w64-mingw32.cmake | 2 - .github/toolchains/x86_64-linux-gnu.cmake | 0 .github/toolchains/x86_64-w64-mingw32.cmake | 2 - .github/workflows/MinedMap.yml | 87 -- CMakeLists.txt | 17 - CMakePresets.json | 39 - src/Buffer.hpp | 71 -- src/CMakeLists.txt | 36 - src/GZip.cpp | 49 - src/GZip.hpp | 18 - src/Info.cpp | 90 -- src/Info.hpp | 84 -- src/MinedMap.cpp | 509 ----------- src/NBT/ByteArrayTag.hpp | 68 -- src/NBT/ByteTag.hpp | 44 - src/NBT/CompoundTag.hpp | 63 -- src/NBT/DoubleTag.hpp | 44 - src/NBT/EndTag.hpp | 32 - src/NBT/FloatTag.hpp | 43 - src/NBT/IntArrayTag.hpp | 68 -- src/NBT/IntTag.hpp | 44 - src/NBT/ListTag.hpp | 59 -- src/NBT/LongArrayTag.hpp | 68 -- src/NBT/LongTag.hpp | 44 - src/NBT/ShortTag.hpp | 44 - src/NBT/StringTag.hpp | 44 - src/NBT/Tag.cpp | 72 -- src/NBT/Tag.hpp | 84 -- src/PNG.cpp | 143 --- src/PNG.hpp | 38 - src/Resource/Biome.cpp | 448 ---------- src/Resource/Biome.hpp | 43 - src/Resource/BlockType.cpp | 68 -- src/Resource/BlockType.hpp | 45 - src/Resource/BlockType.inc.cpp | 938 -------------------- src/Resource/Color.hpp | 52 -- src/Resource/LegacyBlockType.inc.cpp | 597 ------------- src/UniqueCPtr.hpp | 20 - src/Util.hpp | 44 - src/World/Block.hpp | 40 - src/World/Chunk.cpp | 201 ----- src/World/Chunk.hpp | 97 -- src/World/ChunkData.cpp | 78 -- src/World/ChunkData.hpp | 41 - src/World/Level.cpp | 37 - src/World/Level.hpp | 33 - src/World/Region.cpp | 89 -- src/World/Region.hpp | 42 - src/World/Section.cpp | 230 ----- src/World/Section.hpp | 142 --- src/nbtdump.cpp | 36 - src/regiondump.cpp | 32 - 53 files changed, 5375 deletions(-) delete mode 100644 .github/toolchains/common-w64-mingw32.cmake delete mode 100644 .github/toolchains/i686-w64-mingw32.cmake delete mode 100644 .github/toolchains/x86_64-linux-gnu.cmake delete mode 100644 .github/toolchains/x86_64-w64-mingw32.cmake delete mode 100644 CMakeLists.txt delete mode 100644 CMakePresets.json delete mode 100644 src/Buffer.hpp delete mode 100644 src/CMakeLists.txt delete mode 100644 src/GZip.cpp delete mode 100644 src/GZip.hpp delete mode 100644 src/Info.cpp delete mode 100644 src/Info.hpp delete mode 100644 src/MinedMap.cpp delete mode 100644 src/NBT/ByteArrayTag.hpp delete mode 100644 src/NBT/ByteTag.hpp delete mode 100644 src/NBT/CompoundTag.hpp delete mode 100644 src/NBT/DoubleTag.hpp delete mode 100644 src/NBT/EndTag.hpp delete mode 100644 src/NBT/FloatTag.hpp delete mode 100644 src/NBT/IntArrayTag.hpp delete mode 100644 src/NBT/IntTag.hpp delete mode 100644 src/NBT/ListTag.hpp delete mode 100644 src/NBT/LongArrayTag.hpp delete mode 100644 src/NBT/LongTag.hpp delete mode 100644 src/NBT/ShortTag.hpp delete mode 100644 src/NBT/StringTag.hpp delete mode 100644 src/NBT/Tag.cpp delete mode 100644 src/NBT/Tag.hpp delete mode 100644 src/PNG.cpp delete mode 100644 src/PNG.hpp delete mode 100644 src/Resource/Biome.cpp delete mode 100644 src/Resource/Biome.hpp delete mode 100644 src/Resource/BlockType.cpp delete mode 100644 src/Resource/BlockType.hpp delete mode 100644 src/Resource/BlockType.inc.cpp delete mode 100644 src/Resource/Color.hpp delete mode 100644 src/Resource/LegacyBlockType.inc.cpp delete mode 100644 src/UniqueCPtr.hpp delete mode 100644 src/Util.hpp delete mode 100644 src/World/Block.hpp delete mode 100644 src/World/Chunk.cpp delete mode 100644 src/World/Chunk.hpp delete mode 100644 src/World/ChunkData.cpp delete mode 100644 src/World/ChunkData.hpp delete mode 100644 src/World/Level.cpp delete mode 100644 src/World/Level.hpp delete mode 100644 src/World/Region.cpp delete mode 100644 src/World/Region.hpp delete mode 100644 src/World/Section.cpp delete mode 100644 src/World/Section.hpp delete mode 100644 src/nbtdump.cpp delete mode 100644 src/regiondump.cpp diff --git a/.github/toolchains/common-w64-mingw32.cmake b/.github/toolchains/common-w64-mingw32.cmake deleted file mode 100644 index 7fcee75..0000000 --- a/.github/toolchains/common-w64-mingw32.cmake +++ /dev/null @@ -1,16 +0,0 @@ -set(BUILD_STATIC ON) - -set(CMAKE_SYSTEM_NAME Windows) -set(CMAKE_SYSROOT /usr/${TARGET}) - -set(CMAKE_C_COMPILER ${TARGET}-gcc) -set(CMAKE_CXX_COMPILER ${TARGET}-g++) - -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - -set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/lib/pkgconfig:${CMAKE_SYSROOT}/share/pkgconfig) -set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_LIBDIR}) - -set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) diff --git a/.github/toolchains/i686-w64-mingw32.cmake b/.github/toolchains/i686-w64-mingw32.cmake deleted file mode 100644 index 7d1612a..0000000 --- a/.github/toolchains/i686-w64-mingw32.cmake +++ /dev/null @@ -1,2 +0,0 @@ -set(TARGET i686-w64-mingw32) -include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake) diff --git a/.github/toolchains/x86_64-linux-gnu.cmake b/.github/toolchains/x86_64-linux-gnu.cmake deleted file mode 100644 index e69de29..0000000 diff --git a/.github/toolchains/x86_64-w64-mingw32.cmake b/.github/toolchains/x86_64-w64-mingw32.cmake deleted file mode 100644 index cab56f4..0000000 --- a/.github/toolchains/x86_64-w64-mingw32.cmake +++ /dev/null @@ -1,2 +0,0 @@ -set(TARGET x86_64-w64-mingw32) -include(${CMAKE_CURRENT_LIST_DIR}/common-w64-mingw32.cmake) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 1318eab..66edb82 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -2,93 +2,6 @@ name: 'MinedMap' on: ['push', 'pull_request', 'workflow_dispatch'] jobs: - build: - name: 'Build MinedMap (${{ matrix.host }})' - runs-on: 'ubuntu-20.04' - strategy: - fail-fast: false - matrix: - host: - - 'x86_64-linux-gnu' - - 'x86_64-w64-mingw32' - include: - - host: 'x86_64-linux-gnu' - label: 'x86_64-linux-gnu' - packages: ['g++', 'libpng-dev'] - prefix: '/usr' - build_libpng: false - - host: 'x86_64-w64-mingw32' - label: 'Win64' - packages: ['g++-mingw-w64-x86-64', 'libz-mingw-w64-dev'] - prefix: '/usr/x86_64-w64-mingw32' - build_libpng: true - - host: 'i686-w64-mingw32' - label: 'Win32' - packages: ['g++-mingw-w64-i686', 'libz-mingw-w64-dev'] - prefix: '/usr/i686-w64-mingw32' - build_libpng: true - - env: - CMAKE_TOOLCHAIN_FILE: '${{ github.workspace }}/.github/toolchains/${{ matrix.host }}.cmake' - - steps: - - name: 'Checkout' - uses: 'actions/checkout@v3' - - - 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: 'Dependencies (apt)' - run: | - sudo apt-get -y update - sudo apt-get -y install ninja-build ${{ join(matrix.packages, ' ') }} - sudo apt-get -y clean - - - name: 'Dependencies (libpng)' - if: '${{ matrix.build_libpng }}' - run: | - pkgver=1.6.37 - pkghash=505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca - - mkdir -p build/libpng - cd build/libpng - wget http://downloads.sourceforge.net/sourceforge/libpng/libpng-$pkgver.tar.xz - echo "$pkghash libpng-$pkgver.tar.xz" | sha256sum -c - - tar xf libpng-$pkgver.tar.xz - cd libpng-$pkgver - ./configure \ - --prefix=${{ matrix.prefix }} \ - --host=${{ matrix.host }} \ - --disable-shared - make -j$(nproc) - sudo make install - sudo rm ${{ matrix.prefix }}/lib/libpng*.la - - - name: 'Build' - uses: lukka/run-cmake@v10 - with: - configurePreset: 'ninja' - buildPreset: 'ninja-release' - - - name: 'Install' - run: | - export DESTDIR="$(pwd)/build/install" - ninja -C builds/ninja -f build-RelWithDebInfo.ninja install/strip - - pkgdir='build/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' - mkdir -p "$pkgdir" - cp "$DESTDIR/usr/local/bin"/* "$pkgdir"/ - - - name: 'Archive' - uses: 'actions/upload-artifact@v3' - with: - name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' - path: 'build/pkg' - viewer: name: 'Package viewer' runs-on: 'ubuntu-20.04' diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 996ec67..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(MINEDMAP CXX) - -# May not work with all toolchains, added for the Windows CI build -option(BUILD_STATIC "Create a statically linked MinedMap executable") - -if(BUILD_STATIC) - list(REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".dll.a") - add_link_options("-static") -endif() - -find_package(PkgConfig REQUIRED) - -pkg_check_modules(ZLIB REQUIRED IMPORTED_TARGET zlib) -pkg_check_modules(PNG REQUIRED IMPORTED_TARGET libpng16) - -add_subdirectory(src) diff --git a/CMakePresets.json b/CMakePresets.json deleted file mode 100644 index bc371b3..0000000 --- a/CMakePresets.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "version": 3, - "cmakeMinimumRequired": { - "major": 3, - "minor": 7, - "patch": 0 - }, - "configurePresets": [ - { - "name": "ninja", - "displayName": "Ninja", - "description": "Generate Ninja project files", - "binaryDir": "${sourceDir}/builds/${presetName}", - "generator": "Ninja Multi-Config", - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": { - "type": "FILEPATH", - "value": "$env{CMAKE_TOOLCHAIN_FILE}" - } - } - } - ], - "buildPresets": [ - { - "name": "ninja-debug", - "configurePreset": "ninja", - "displayName": "Build ninja-debug", - "description": "Build ninja Debug configuration", - "configuration": "Debug" - }, - { - "name": "ninja-release", - "configurePreset": "ninja", - "displayName": "Build ninja-release", - "description": "Build ninja Release configuration", - "configuration": "RelWithDebInfo" - } - ] -} diff --git a/src/Buffer.hpp b/src/Buffer.hpp deleted file mode 100644 index 89d4649..0000000 --- a/src/Buffer.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include -#include -#include - - -namespace MinedMap { - -class Buffer { -private: - const uint8_t *data; - size_t len; - -public: - static uint16_t parse16(const uint8_t *buf) { - return (buf[0] << 8) | buf[1]; - } - - static uint32_t parse32(const uint8_t *buf) { - return (uint32_t(buf[0]) << 24) | (uint32_t(buf[1]) << 16) | (uint32_t(buf[2]) << 8) | uint32_t(buf[3]); - } - - static uint64_t parse64(const uint8_t *buf) { - return (uint64_t(buf[0]) << 56) | (uint64_t(buf[1]) << 48) | (uint64_t(buf[2]) << 40) | (uint64_t(buf[3]) << 32) - | (uint64_t(buf[4]) << 24) | (uint64_t(buf[5]) << 16) | (uint64_t(buf[6]) << 8) | uint64_t(buf[7]); - } - - - Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {} - - size_t getRemaining() const { - return len; - } - - const uint8_t * get(size_t n) { - if (n > len) - throw std::runtime_error("Buffer::get(): buffer underrun"); - - data += n; - len -= n; - return (data - n); - } - - uint8_t get8() { - return *get(1); - } - - uint16_t get16() { - return parse16(get(2)); - } - - uint32_t get32() { - return parse32(get(4)); - } - - uint64_t get64() { - return parse64(get(8)); - } - -}; - -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 0e4fd48..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -add_compile_options(-std=c++11 -Wall) - -add_executable(MinedMap - MinedMap.cpp - GZip.cpp - Info.cpp - PNG.cpp - - NBT/Tag.cpp - Resource/Biome.cpp - Resource/BlockType.cpp - World/Chunk.cpp - World/ChunkData.cpp - World/Level.cpp - World/Region.cpp - World/Section.cpp -) -target_link_libraries(MinedMap PkgConfig::ZLIB PkgConfig::PNG) - -add_executable(nbtdump - nbtdump.cpp - GZip.cpp - NBT/Tag.cpp -) -target_link_libraries(nbtdump PkgConfig::ZLIB) - -add_executable(regiondump - regiondump.cpp - GZip.cpp - NBT/Tag.cpp - World/ChunkData.cpp - World/Region.cpp -) -target_link_libraries(regiondump PkgConfig::ZLIB) - -install(TARGETS MinedMap RUNTIME DESTINATION bin) diff --git a/src/GZip.cpp b/src/GZip.cpp deleted file mode 100644 index 28f4737..0000000 --- a/src/GZip.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#include "GZip.hpp" - -#include -#include -#include - - -namespace MinedMap { - -std::vector readGZip(const char *filename) { - std::vector buffer; - size_t len = 0; - - gzFile f = gzopen(filename, "rb"); - if (!f) - throw std::system_error( - errno, std::generic_category(), - (std::string("unable to open file ") + filename).c_str() - ); - - while (true) { - if ((buffer.size() - len) < 4096) - buffer.resize(buffer.size() + 4096); - - int r = gzread(f, buffer.data()+len, buffer.size()-len); - if (r < 0) - throw std::system_error(errno, std::generic_category(), "error reading GZip file"); - - if (!r) - break; - - len += r; - } - - gzclose_r(f); - - buffer.resize(len); - - return buffer; -} - -} diff --git a/src/GZip.hpp b/src/GZip.hpp deleted file mode 100644 index 8449758..0000000 --- a/src/GZip.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include - - -namespace MinedMap { - -std::vector readGZip(const char *filename); - -} diff --git a/src/Info.cpp b/src/Info.cpp deleted file mode 100644 index 48bbb45..0000000 --- a/src/Info.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#include "Info.hpp" - -#include -#include -#include -#include - - -namespace MinedMap { - -void Info::writeJSON(const char *filename) const { - const std::string tmpfile = std::string(filename) + ".tmp"; - - FILE *f = std::fopen(tmpfile.c_str(), "w"); - if (!f) { - std::fprintf(stderr, "Unable to open %s: %s\n", tmpfile.c_str(), std::strerror(errno)); - return; - } - - std::fprintf(f, "{"); - std::fprintf(f, "\"mipmaps\":["); - - bool first_level = true; - for (const auto &level : levels) { - if (!first_level) - std::fprintf(f, ","); - first_level = false; - - int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = level.bounds; - - std::fprintf(f, "{"); - std::fprintf(f, "\"bounds\":{"); - std::fprintf(f, "\"minX\":%i,", minX); - std::fprintf(f, "\"maxX\":%i,", maxX); - std::fprintf(f, "\"minZ\":%i,", minZ); - std::fprintf(f, "\"maxZ\":%i", maxZ); - std::fprintf(f, "},"); - std::fprintf(f, "\"regions\":{"); - - bool first_z = true; - for (const auto &item : level.regions) { - if (!first_z) - std::fprintf(f, ","); - first_z = false; - - int z = item.first; - const std::set &z_regions = item.second; - - std::fprintf(f, "\"%d\":[", z); - - bool first_x = true; - for (int x : z_regions) { - if (!first_x) - std::fprintf(f, ","); - first_x = false; - - - std::fprintf(f, "%d", x); - } - - std::fprintf(f, "]"); - } - - std::fprintf(f, "}}"); - } - - std::fprintf(f, "],"); - std::fprintf(f, "\"spawn\":{"); - std::fprintf(f, "\"x\":%li,", (long)spawnX); - std::fprintf(f, "\"z\":%li", (long)spawnZ); - std::fprintf(f, "}"); - std::fprintf(f, "}"); - - std::fclose(f); - - if (std::rename(tmpfile.c_str(), filename) < 0) { - std::fprintf(stderr, "Unable to save %s: %s\n", filename, std::strerror(errno)); - std::remove(tmpfile.c_str()); - } -} - -} diff --git a/src/Info.hpp b/src/Info.hpp deleted file mode 100644 index 4ab7dd3..0000000 --- a/src/Info.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace MinedMap { - -class Info { -public: - typedef std::function RegionVisitor; - - struct Level { - std::map> regions; - std::tuple bounds; - }; - -private: - std::vector levels; - - int32_t spawnX, spawnZ; - -public: - Info() : spawnX(0), spawnZ(0) { - addMipmapLevel(); - } - - std::tuple getBounds(size_t level) const { - return levels[level].bounds; - } - - void addRegion(int x, int z, size_t level) { - auto &the_level = levels[level]; - auto z_regions = the_level.regions.emplace( - std::piecewise_construct, - std::make_tuple(z), - std::make_tuple()).first; - z_regions->second.insert(x); - - std::tuple &b = the_level.bounds; - - if (x < std::get<0>(b)) std::get<0>(b) = x; - if (x > std::get<1>(b)) std::get<1>(b) = x; - if (z < std::get<2>(b)) std::get<2>(b) = z; - if (z > std::get<3>(b)) std::get<3>(b) = z; - } - - void addMipmapLevel() { - levels.emplace_back(Level { - .regions = {}, - .bounds = {INT_MAX, INT_MIN, INT_MAX, INT_MIN}, - }); - } - - void visitRegions(size_t level, const RegionVisitor &visitor) const { - for (const auto &item : levels[level].regions) { - int z = item.first; - for (int x : item.second) - visitor(x, z); - } - } - - void setSpawn(const std::pair &v) { - std::tie(spawnX, spawnZ) = v; - } - - void writeJSON(const char *filename) const; -}; - -} diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp deleted file mode 100644 index 7103d89..0000000 --- a/src/MinedMap.cpp +++ /dev/null @@ -1,509 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#include "Info.hpp" -#include "PNG.hpp" -#include "World/Level.hpp" -#include "World/Region.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -namespace MinedMap { - -static const int BIOME_SMOOTH = 3; -static const uint32_t DIM = World::Region::SIZE*World::Chunk::SIZE; - - -static void addChunkBiome(uint8_t biomemap[DIM*DIM], chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *data) { - World::Chunk chunk(data); - World::Chunk::Heightmap layer = chunk.getTopLayer(0); - - for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) { - for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) { - size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; - const World::Chunk::Height &height = layer.v[x][z]; - biomemap[i] = chunk.getBiome(x, height.y, z); - } - } -} - -static uint8_t biomeAt(int16_t x, int16_t z, const std::unique_ptr biomemaps[3][3]) { - size_t a = 1, b = 1; - - if (x < 0) { - a--; - x += DIM; - } else if (x >= (int32_t)DIM) { - a++; - x -= DIM; - } - if (z < 0) { - b--; - z += DIM; - } else if (z >= (int32_t)DIM) { - b++; - z -= DIM; - } - - return biomemaps[a][b].get()[z*DIM + x]; -} - -static Resource::Color collectColors( - region_block_idx_t x, region_block_idx_t z, - const World::Block &block, const std::unique_ptr biomemaps[3][3] -) { - std::unordered_map biomes; - for (int16_t dx = -BIOME_SMOOTH; dx <= BIOME_SMOOTH; dx++) { - for (int16_t dz = -BIOME_SMOOTH; dz <= BIOME_SMOOTH; dz++) { - if (std::abs(dx) + std::abs(dz) > BIOME_SMOOTH) - continue; - - uint8_t biome = biomeAt(x+dx, z+dz, biomemaps); - if (biomes.count(biome)) - biomes[biome]++; - else - biomes[biome] = 1; - } - } - - Resource::FloatColor c = {}; - unsigned total = 0; - - for (const auto &e : biomes) { - uint8_t biome = e.first; - unsigned count = e.second; - - if (biome == 0xff) - continue; - - c = c + count * block.getColor(biome); - total += count; - } - - if (!total) - return block.getColor(0); - - return (1.0f / total) * c; -} - -static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], chunk_idx_t X, chunk_idx_t Z, - const World::ChunkData *data, const std::unique_ptr biomemaps[3][3] -) { - World::Chunk chunk(data); - World::Chunk::Heightmap layer = chunk.getTopLayer(World::Chunk::WITH_DEPTH); - - for (block_idx_t x = 0; x < World::Chunk::SIZE; x++) { - for (block_idx_t z = 0; z < World::Chunk::SIZE; z++) { - size_t i = (Z*World::Chunk::SIZE+z)*DIM + X*World::Chunk::SIZE+x; - const World::Chunk::Height &height = layer.v[x][z]; - World::Block block = chunk.getBlock(x, height, z); - - if (!block.isVisible()) - continue; - - image[i] = collectColors(X*World::Chunk::SIZE+x, Z*World::Chunk::SIZE+z, block, biomemaps); - lightmap[2*i+1] = (1 - block.blockLight/15.f)*192; - } - } -} - -static int64_t readStamp(const std::string &filename) { - int64_t v = INT64_MIN; - - std::FILE *f = std::fopen((filename + ".stamp").c_str(), "r"); - if (f) { - if (std::fscanf(f, "%" SCNd64, &v) != 1) { - // Ignore errors - } - std::fclose(f); - } - - return v; -} - -static void writeStamp(const std::string &filename, int64_t v) { - std::FILE *f = std::fopen((filename + ".stamp").c_str(), "w"); - if (f) { - std::fprintf(f, "%" PRId64, v); - std::fclose(f); - } -} - -static bool writeImage(const std::string &output, const uint8_t *data, PNG::Format format, int64_t t) { - const std::string tmpfile = output + ".tmp"; - - size_t len = PNG::formatBytes(format)*DIM*DIM; - bool changed = true; - - try { - std::unique_ptr old(new uint8_t[len]); - PNG::read(output.c_str(), old.get(), DIM, DIM, format); - - if (std::memcmp(data, old.get(), len) == 0) - changed = false; - } catch (const std::exception& ex) { - } - - try { - if (changed) { - PNG::write(tmpfile.c_str(), data, DIM, DIM, format); - - if (std::rename(tmpfile.c_str(), output.c_str()) < 0) { - std::fprintf(stderr, "Unable to save %s: %s\n", output.c_str(), std::strerror(errno)); - std::remove(tmpfile.c_str()); - } - } - - writeStamp(output, t); - } catch (const std::exception& ex) { - std::remove(tmpfile.c_str()); - throw; - } - - return changed; -} - -static int64_t getModTime(const std::string &file) { - struct stat s; - if (stat(file.c_str(), &s) < 0) { - if (errno != ENOENT) - std::fprintf(stderr, "Unable to stat %s: %s\n", file.c_str(), std::strerror(errno)); - return INT64_MIN; - } - -#if defined(_WIN32) - return (int64_t)s.st_mtime * 1000000; -#elif defined(__APPLE__) - return (int64_t)s.st_mtimespec.tv_sec * 1000000 + s.st_mtimespec.tv_nsec / 1000; -#else - return (int64_t)s.st_mtim.tv_sec * 1000000 + s.st_mtim.tv_nsec / 1000; -#endif -} - -static bool checkRegion(int64_t changed, const std::string &file) { - struct stat s; - if (stat(file.c_str(), &s) < 0) - return true; - - int64_t outtime = readStamp(file); - if (changed <= outtime) { - std::printf("%s is up-to-date.\n", file.c_str()); - return false; - } - - return true; -} - -template -static std::string format(const T &v) { - std::ostringstream s; - - s << v; - return s.str(); -} - -static std::string formatTileName(int x, int z, const std::string &ext) { - std::ostringstream s; - - s << "r." << x << "." << z << "." << ext; - return s.str(); -} - -static bool checkFilename(const char *name, int *x, int *z) { - if (std::sscanf(name, "r.%i.%i.mca", x, z) != 2) - return false; - - return (std::string(name) == formatTileName(*x, *z, "mca")); -} - -static void makeDir(const std::string &name) { - if ( - mkdir( - name.c_str() -#ifndef _WIN32 - , 0777 -#endif - ) < 0 && errno != EEXIST - ) - throw std::system_error(errno, std::generic_category(), "unable to create directory " + name); -} - -static void makeBiome(const std::string ®iondir, const std::string &outputdir, int x, int z) { - std::string inname = formatTileName(x, z, "mca"); - std::string outname = formatTileName(x, z, "png"); - std::string input = regiondir + "/" + inname, output = outputdir + "/biome/" + outname; - - int64_t intime = getModTime(input); - if (intime == INT64_MIN) - return; - - if (!checkRegion(intime, output)) - return; - - std::printf("Generating %s from %s... ", output.c_str(), input.c_str()); - std::fflush(stdout); - - try { - std::unique_ptr biomemap(new uint8_t[DIM*DIM]); - std::memset(biomemap.get(), 0xff, DIM*DIM); - - World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { - addChunkBiome(biomemap.get(), X, Z, chunk); - }); - - bool changed = writeImage(output, biomemap.get(), PNG::GRAY, intime); - std::printf("%s.\n", changed ? "done" : "unchanged"); - } catch (const std::exception& ex) { - std::fprintf(stderr, "Failed to generate %s: %s\n", output.c_str(), ex.what()); - } -} - -static void makeBiomes(const std::string ®iondir, const std::string &outputdir, const Info *info) { - info->visitRegions(0, [&] (int x, int z) { - makeBiome(regiondir, outputdir, x, z); - }); -} - -static void makeMap(const std::string ®iondir, const std::string &outputdir, int x, int z) { - std::string inname = formatTileName(x, z, "mca"); - std::string outname = formatTileName(x, z, "png"); - std::string input = regiondir + "/" + inname; - std::string output = outputdir + "/map/0/" + outname, output_light = outputdir + "/light/0/" + outname; - std::string biomenames[3][3]; - - int64_t intime = getModTime(input); - if (intime == INT64_MIN) - return; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - biomenames[i][j] = outputdir + "/biome/" + formatTileName(x + i - 1, z + j - 1, "png"); - intime = std::max(intime, getModTime(biomenames[i][j])); - } - } - - if (!checkRegion(intime, output)) - return; - - std::printf("Generating %s from %s... ", output.c_str(), input.c_str()); - std::fflush(stdout); - - try { - std::unique_ptr biomemaps[3][3]; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - biomemaps[i][j].reset(new uint8_t[DIM*DIM]); - std::memset(biomemaps[i][j].get(), 0, DIM*DIM); - - try { - PNG::read(biomenames[i][j].c_str(), biomemaps[i][j].get(), DIM, DIM, PNG::GRAY); - } catch (const std::exception& ex) {} - } - } - - std::unique_ptr image(new Resource::Color[DIM*DIM]); - - std::unique_ptr lightmap(new uint8_t[2*DIM*DIM]); - std::memset(lightmap.get(), 0, 2*DIM*DIM); - - World::Region::visitChunks(input.c_str(), [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { - addChunk(image.get(), lightmap.get(), X, Z, chunk, biomemaps); - }); - - bool changed = writeImage(output, reinterpret_cast(image.get()), PNG::RGB_ALPHA, intime); - changed = writeImage(output_light, lightmap.get(), PNG::GRAY_ALPHA, intime) || changed; - std::printf("%s.\n", changed ? "done" : "unchanged"); - } catch (const std::exception& ex) { - std::fprintf(stderr, "Failed to generate %s: %s\n", output.c_str(), ex.what()); - } -} - -static void makeMaps(const std::string ®iondir, const std::string &outputdir, const Info *info) { - info->visitRegions(0, [&] (int x, int z) { - makeMap(regiondir, outputdir, x, z); - }); -} - -static bool makeMipmap(const std::string &dir, size_t level, int x, int z, PNG::Format imageFormat) { - bool ret = false; - - std::string indir = dir + "/" + format(level-1) + "/"; - std::string outdir = dir + "/" + format(level) + "/"; - - const std::string nw_str = indir + formatTileName(x*2, z*2, "png"); - const std::string ne_str = indir + formatTileName(x*2+1, z*2, "png"); - const std::string sw_str = indir + formatTileName(x*2, z*2+1, "png"); - const std::string se_str = indir + formatTileName(x*2+1, z*2+1, "png"); - - const char *nw = nw_str.c_str(); - const char *ne = ne_str.c_str(); - const char *sw = sw_str.c_str(); - const char *se = se_str.c_str(); - - int64_t t = INT64_MIN; - unsigned count = 0; - for (auto name : {&nw, &ne, &sw, &se}) { - struct stat s; - if (stat(*name, &s) < 0) { - *name = nullptr; - continue; - } - - int64_t t_part = readStamp(*name); - if (t_part > t) - t = t_part; - - count++; - } - - std::string output = outdir + formatTileName(x, z, "png"); - - { - struct stat s; - if (stat(output.c_str(), &s) == 0) { - ret = true; - - int64_t outtime = readStamp(output); - if (t <= outtime) - return ret; - } - } - - if (!count) - return ret; - - const std::string tmpfile = output + ".tmp"; - - try { - PNG::mipmap(tmpfile.c_str(), DIM, DIM, imageFormat, nw, ne, sw, se); - - if (std::rename(tmpfile.c_str(), output.c_str()) < 0) { - std::fprintf(stderr, "Unable to save %s: %s\n", output.c_str(), std::strerror(errno)); - std::remove(tmpfile.c_str()); - } - - writeStamp(output, t); - } catch (const std::exception& ex) { - std::remove(tmpfile.c_str()); - throw; - } - - return true; -} - -static int floored_half(int a) { - return (a - (a < 0)) / 2; -} - -static void makeMipmaps(const std::string &dir, Info *info) { - for (size_t level = 0; ; level++) { - int minX, maxX, minZ, maxZ; - std::tie(minX, maxX, minZ, maxZ) = info->getBounds(level); - - if (minX >= -1 && maxX <= 0 && minZ >= -1 && maxZ <= 0) - break; - - info->addMipmapLevel(); - makeDir(dir + "/map/" + format(level + 1)); - makeDir(dir + "/light/" + format(level + 1)); - - info->visitRegions(level, [&] (int x, int z) { - info->addRegion(floored_half(x), floored_half(z), level + 1); - }); - - info->visitRegions(level + 1, [&] (int x, int z) { - if (makeMipmap(dir + "/map", level + 1, x, z, PNG::RGB_ALPHA)) - info->addRegion(x, z, level + 1); - - makeMipmap(dir + "/light", level + 1, x, z, PNG::GRAY_ALPHA); - }); - } -} - -static Info collectInfo(const std::string ®iondir) { - DIR *dir = opendir(regiondir.c_str()); - if (!dir) - throw std::system_error(errno, std::generic_category(), "Unable to read input directory"); - - Info info; - - struct dirent *entry; - while ((entry = readdir(dir)) != nullptr) { - int x, z; - if (!checkFilename(entry->d_name, &x, &z)) - continue; - - info.addRegion(x, z, 0); - - } - - closedir(dir); - - return info; -} - -static void doLevel(const std::string &inputdir, const std::string &outputdir) { - const std::string regiondir = inputdir + "/region"; - - makeDir(outputdir + "/biome"); - makeDir(outputdir + "/map"); - makeDir(outputdir + "/map/0"); - makeDir(outputdir + "/light"); - makeDir(outputdir + "/light/0"); - - Info info = collectInfo(regiondir); - - std::printf("Updating biome data...\n"); - makeBiomes(regiondir, outputdir, &info); - - std::printf("Updating map data...\n"); - makeMaps(regiondir, outputdir, &info); - - World::Level level((inputdir + "/level.dat").c_str()); - info.setSpawn(level.getSpawn()); - - std::printf("Updating mipmaps...\n"); - makeMipmaps(outputdir, &info); - - info.writeJSON((outputdir + "/info.json").c_str()); -} - -} - - -int main(int argc, char *argv[]) { - if (argc < 3) { - std::fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - try { - MinedMap::doLevel(argv[1], argv[2]); - } catch (const std::runtime_error& ex) { - std::fprintf(stderr, "Error: %s\n", ex.what()); - return 1; - } - - return 0; -} diff --git a/src/NBT/ByteArrayTag.hpp b/src/NBT/ByteArrayTag.hpp deleted file mode 100644 index 9c73647..0000000 --- a/src/NBT/ByteArrayTag.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - -#include - - -namespace MinedMap { -namespace NBT { - -class ByteArrayTag : public Tag { -private: - uint32_t len; - const uint8_t *ptr; - -public: - static const MakeType Type; - - - ByteArrayTag(Buffer *buffer) { - len = buffer->get32(); - ptr = buffer->get(len); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &indent) const { - os << "(" << len << ") [" << std::endl; - - std::string inner = indent + " "; - - for (size_t i = 0; i < len; i++) { - uint8_t v = ptr[i]; - - os << inner - << (unsigned)v << " / " - << (int)(int8_t)v << " / " - << std::hex << "0x" << (unsigned)v << std::dec - << std::endl; - } - - os << indent << "]"; - } - - uint32_t getLength() const { - return len; - } - - const uint8_t * getPointer() const { - return ptr; - } - - uint8_t getValue(size_t i) const { - return ptr[i]; - } -}; - -} -} diff --git a/src/NBT/ByteTag.hpp b/src/NBT/ByteTag.hpp deleted file mode 100644 index 7d3fff5..0000000 --- a/src/NBT/ByteTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class ByteTag : public Tag { -private: - uint8_t value; - -public: - static const MakeType Type; - - - ByteTag(Buffer *buffer) { - value = buffer->get8(); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - os << (unsigned)getValue() << " / " - << (int)(int8_t)getValue() << " / " - << std::hex << "0x" << (unsigned)getValue() << std::dec; - } - - uint8_t getValue() const { - return value; - } -}; - -} -} diff --git a/src/NBT/CompoundTag.hpp b/src/NBT/CompoundTag.hpp deleted file mode 100644 index b1e7521..0000000 --- a/src/NBT/CompoundTag.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "EndTag.hpp" -#include "Tag.hpp" - -#include -#include - - -namespace MinedMap { -namespace NBT { - -class CompoundTag : public Tag, public std::unordered_map> { -public: - static const MakeType Type; - - - CompoundTag(Buffer *buffer) { - while (true) { - std::pair> v = Tag::readNamedTag(buffer); - if (v.second->getType() == EndTag::Type) - break; - - insert(std::move(v)); - } - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &indent) const { - os << "{" << std::endl; - - std::string inner = indent + " "; - - for (const auto &item : *this) { - os << inner << item.first << ": " << item.second->getType() << " "; - item.second->print(os, inner); - os << std::endl; - } - - os << indent << "}"; - } - - template std::shared_ptr get(const std::string &key) const { - auto it = find(key); - if (it == end()) - return std::shared_ptr(); - - return std::dynamic_pointer_cast(it->second); - } -}; - -} -} diff --git a/src/NBT/DoubleTag.hpp b/src/NBT/DoubleTag.hpp deleted file mode 100644 index a28c38a..0000000 --- a/src/NBT/DoubleTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class DoubleTag : public Tag { -private: - const uint8_t *ptr; - -public: - static const MakeType Type; - - - DoubleTag(Buffer *buffer) { - ptr = buffer->get(8); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - union { - uint64_t i; - double d; - }; - - i = Buffer::parse64(ptr); - os << d; - } -}; - -} -} diff --git a/src/NBT/EndTag.hpp b/src/NBT/EndTag.hpp deleted file mode 100644 index 859d77a..0000000 --- a/src/NBT/EndTag.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class EndTag : public Tag { -public: - static const MakeType Type; - - - EndTag(Buffer *) {} - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream&, const std::string &) const { - } -}; - -} -} diff --git a/src/NBT/FloatTag.hpp b/src/NBT/FloatTag.hpp deleted file mode 100644 index 637c74b..0000000 --- a/src/NBT/FloatTag.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class FloatTag : public Tag { - const uint8_t *ptr; - -public: - static const MakeType Type; - - - FloatTag(Buffer *buffer) { - ptr = buffer->get(4); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - union { - uint32_t i; - float f; - }; - - i = Buffer::parse32(ptr); - os << f; - } -}; - -} -} diff --git a/src/NBT/IntArrayTag.hpp b/src/NBT/IntArrayTag.hpp deleted file mode 100644 index cc24665..0000000 --- a/src/NBT/IntArrayTag.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - -#include - - -namespace MinedMap { -namespace NBT { - -class IntArrayTag : public Tag { -private: - uint32_t len; - const uint8_t *ptr; - -public: - static const MakeType Type; - - - IntArrayTag(Buffer *buffer) { - len = buffer->get32(); - ptr = buffer->get(4*len); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &indent) const { - os << "(" << len << ") [" << std::endl; - - std::string inner = indent + " "; - - for (size_t i = 0; i < len; i++) { - uint32_t v = getValue(i); - - os << inner - << v << " / " - << (int32_t)v << " / " - << std::hex << "0x" << v << std::dec - << std::endl; - } - - os << indent << "]"; - } - - uint32_t getLength() const { - return len; - } - - const uint8_t * getPointer() const { - return ptr; - } - - uint32_t getValue(size_t i) const { - return Buffer::parse32(&ptr[4*i]); - } -}; - -} -} diff --git a/src/NBT/IntTag.hpp b/src/NBT/IntTag.hpp deleted file mode 100644 index b2c2660..0000000 --- a/src/NBT/IntTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class IntTag : public Tag { -private: - const uint8_t *ptr; - -public: - static const MakeType Type; - - - IntTag(Buffer *buffer) { - ptr = buffer->get(4); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - os << getValue() << " / " - << (int32_t)getValue() << " / " - << std::hex << "0x" << getValue() << std::dec; - } - - uint32_t getValue() const { - return Buffer::parse32(ptr); - } -}; - -} -} diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp deleted file mode 100644 index 6582098..0000000 --- a/src/NBT/ListTag.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - -#include - - -namespace MinedMap { -namespace NBT { - -class ListTag : public Tag, public std::vector> { -private: - const TagType *subtype; - -public: - static const MakeType Type; - - - ListTag(Buffer *buffer) { - subtype = &getTypeById(buffer->get8()); - - uint32_t len = buffer->get32(); - - for (uint32_t i = 0; i < len; i++) - push_back(subtype->read(buffer)); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual const TagType & getSubtype() const { - return *subtype; - } - - virtual void print(std::ostream& os, const std::string &indent) const { - os << getSubtype() << " [" << std::endl; - - std::string inner = indent + " "; - - for (const auto &item : *this) { - os << inner; - item->print(os, inner); - os << std::endl; - } - - os << indent << "]"; - } -}; - -} -} diff --git a/src/NBT/LongArrayTag.hpp b/src/NBT/LongArrayTag.hpp deleted file mode 100644 index 2e54762..0000000 --- a/src/NBT/LongArrayTag.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2018, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - -#include - - -namespace MinedMap { -namespace NBT { - -class LongArrayTag : public Tag { -private: - uint32_t len; - const uint8_t *ptr; - -public: - static const MakeType Type; - - - LongArrayTag(Buffer *buffer) { - len = buffer->get32(); - ptr = buffer->get(8*len); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &indent) const { - os << "(" << len << ") [" << std::endl; - - std::string inner = indent + " "; - - for (size_t i = 0; i < len; i++) { - uint64_t v = Buffer::parse64(&ptr[8*i]); - - os << inner - << v << " / " - << (int64_t)v << " / " - << std::hex << "0x" << v << std::dec - << std::endl; - } - - os << indent << "]"; - } - - uint32_t getLength() const { - return len; - } - - const uint8_t * getPointer() const { - return ptr; - } - - uint64_t getValue(size_t i) const { - return Buffer::parse64(&ptr[8*i]); - } -}; - -} -} diff --git a/src/NBT/LongTag.hpp b/src/NBT/LongTag.hpp deleted file mode 100644 index 450f6b4..0000000 --- a/src/NBT/LongTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class LongTag : public Tag { -private: - const uint8_t *ptr; - -public: - static const MakeType Type; - - - LongTag(Buffer *buffer) { - ptr = buffer->get(8); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - os << getValue() << " / " - << (int64_t)getValue() << " / " - << std::hex << "0x" << getValue() << std::dec; - } - - uint64_t getValue() const { - return Buffer::parse64(ptr); - } -}; - -} -} diff --git a/src/NBT/ShortTag.hpp b/src/NBT/ShortTag.hpp deleted file mode 100644 index 32f32a2..0000000 --- a/src/NBT/ShortTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class ShortTag : public Tag { -private: - const uint8_t *ptr; - -public: - static const MakeType Type; - - - ShortTag(Buffer *buffer) { - ptr = buffer->get(2); - } - - virtual const TagType & getType() const { - return Type; - } - - virtual void print(std::ostream& os, const std::string &) const { - os << getValue() << " / " - << (int16_t)getValue() << " / " - << std::hex << "0x" << getValue() << std::dec; - } - - uint16_t getValue() const { - return Buffer::parse16(ptr); - } -}; - -} -} diff --git a/src/NBT/StringTag.hpp b/src/NBT/StringTag.hpp deleted file mode 100644 index 40c5bfb..0000000 --- a/src/NBT/StringTag.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Tag.hpp" - - -namespace MinedMap { -namespace NBT { - -class StringTag : public Tag { -private: - uint16_t len; - const uint8_t *ptr; - -public: - static const MakeType Type; - - - StringTag(Buffer *buffer) { - len = buffer->get16(); - ptr = buffer->get(len); - } - - virtual const TagType & getType() const { - return Type; - } - - std::string getValue() const { - return std::string(reinterpret_cast(ptr), len); - } - - virtual void print(std::ostream& os, const std::string &) const { - os << "\"" << getValue() << "\""; - } -}; - -} -} diff --git a/src/NBT/Tag.cpp b/src/NBT/Tag.cpp deleted file mode 100644 index 57dd395..0000000 --- a/src/NBT/Tag.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#include "Tag.hpp" - -#include "EndTag.hpp" -#include "ByteTag.hpp" -#include "ShortTag.hpp" -#include "IntTag.hpp" -#include "LongTag.hpp" -#include "FloatTag.hpp" -#include "DoubleTag.hpp" -#include "ByteArrayTag.hpp" -#include "StringTag.hpp" -#include "ListTag.hpp" -#include "CompoundTag.hpp" -#include "IntArrayTag.hpp" -#include "LongArrayTag.hpp" - - -namespace MinedMap { -namespace NBT { - -const Tag::MakeType EndTag::Type("End"); -const Tag::MakeType ByteTag::Type("Byte"); -const Tag::MakeType ShortTag::Type("Short"); -const Tag::MakeType IntTag::Type("Int"); -const Tag::MakeType LongTag::Type("Long"); -const Tag::MakeType FloatTag::Type("Float"); -const Tag::MakeType DoubleTag::Type("Double"); -const Tag::MakeType ByteArrayTag::Type("ByteArray"); -const Tag::MakeType StringTag::Type("String"); -const Tag::MakeType ListTag::Type("List"); -const Tag::MakeType CompoundTag::Type("Compound"); -const Tag::MakeType IntArrayTag::Type("IntArray"); -const Tag::MakeType LongArrayTag::Type("LongArray"); - - -const std::vector Tag::types = { - &EndTag::Type, - &ByteTag::Type, - &ShortTag::Type, - &IntTag::Type, - &LongTag::Type, - &FloatTag::Type, - &DoubleTag::Type, - &ByteArrayTag::Type, - &StringTag::Type, - &ListTag::Type, - &CompoundTag::Type, - &IntArrayTag::Type, - &LongArrayTag::Type, -}; - - -std::pair> Tag::readNamedTag(Buffer *buffer) { - const TagType &type = getTypeById(buffer->get8()); - if (type == EndTag::Type) - return std::make_pair("", std::make_shared(buffer)); - - uint16_t len = buffer->get16(); - std::string name(reinterpret_cast(buffer->get(len)), len); - - return std::make_pair(name, type.read(buffer)); -} - -} -} diff --git a/src/NBT/Tag.hpp b/src/NBT/Tag.hpp deleted file mode 100644 index 98c0ae2..0000000 --- a/src/NBT/Tag.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include -#include -#include - -#include "../Buffer.hpp" - - -namespace MinedMap { -namespace NBT { - -class Tag; - -class TagType { -public: - TagType() = default; - TagType(const TagType&) = delete; - TagType & operator=(const TagType&) = delete; - - virtual const char * getName() const = 0; - virtual std::shared_ptr read(Buffer *buffer) const = 0; - - bool operator==(const TagType &type) const { - return this == &type; - } -}; - -class Tag { -private: - static const std::vector types; - -protected: - template - class MakeType : public TagType { - private: - const char *name; - - public: - MakeType(const char *name0) : name(name0) {} - - virtual const char * getName() const { - return name; - } - - virtual std::shared_ptr read(Buffer *buffer) const { - return std::make_shared(buffer); - } - }; - - - static const TagType & getTypeById(uint8_t id) { - return *types.at(id); - } - -public: - static std::pair> readNamedTag(Buffer *buffer); - - virtual const TagType & getType() const = 0; - virtual void print(std::ostream& os, const std::string &indent) const = 0; - - virtual ~Tag() {} -}; - -static inline std::ostream& operator<<(std::ostream& os, const TagType &type) { - return os << type.getName(); -} - -static inline std::ostream& operator<<(std::ostream& os, const Tag &tag) { - os << tag.getType() << " "; - tag.print(os, ""); - return os; -} - -} -} diff --git a/src/PNG.cpp b/src/PNG.cpp deleted file mode 100644 index 5c2c098..0000000 --- a/src/PNG.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#include "PNG.hpp" - -#include -#include -#include -#include -#include - -#include - - -namespace MinedMap { -namespace PNG { - -static const int formatColorTypes[] = { - [RGB_ALPHA] = PNG_COLOR_TYPE_RGB_ALPHA, - [GRAY_ALPHA] = PNG_COLOR_TYPE_GRAY_ALPHA, - [GRAY] = PNG_COLOR_TYPE_GRAY, -}; - -void write(const char *filename, const uint8_t *data, size_t width, size_t height, Format format) { - std::FILE *f = std::fopen(filename, "wb"); - if (!f) - throw std::system_error(errno, std::generic_category(), "unable to open PNG file"); - - png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png_ptr) - throw std::runtime_error("unable to create PNG write struct"); - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, nullptr); - throw std::runtime_error("unable to create PNG info struct"); - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - std::fclose(f); - throw std::runtime_error("unable to write PNG file"); - } - - png_init_io(png_ptr, f); - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, formatColorTypes[format], - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - uint8_t *row_pointers[height]; - for (size_t i = 0; i < height; i++) - row_pointers[i] = const_cast(&data[formatBytes(format)*i*width]); - - png_set_rows(png_ptr, info_ptr, row_pointers); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - - png_destroy_write_struct(&png_ptr, &info_ptr); - std::fclose(f); -} - -void read(const char *filename, uint8_t *data, size_t width, size_t height, Format format) { - std::FILE *f = std::fopen(filename, "rb"); - if (!f) - throw std::system_error(errno, std::generic_category(), "unable to open PNG file"); - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png_ptr) - throw std::runtime_error("unable to create PNG read struct"); - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, nullptr, nullptr); - throw std::runtime_error("unable to create PNG info struct"); - } - - png_infop end_info = png_create_info_struct(png_ptr); - if (!end_info) { - png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - throw std::runtime_error("unable to create PNG info struct"); - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - fclose(f); - throw std::runtime_error("unable to read PNG file"); - } - - png_init_io(png_ptr, f); - - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - - if (png_get_image_width(png_ptr, info_ptr) != width - || png_get_image_height(png_ptr, info_ptr) != height - || png_get_bit_depth(png_ptr, info_ptr) != 8 - || png_get_color_type(png_ptr, info_ptr) != formatColorTypes[format]) - longjmp(png_jmpbuf(png_ptr), 1); - - uint8_t **row_pointers = png_get_rows(png_ptr, info_ptr); - for (size_t i = 0; i < height; i++) - std::memcpy(&data[formatBytes(format)*i*width], row_pointers[i], formatBytes(format)*width); - - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - std::fclose(f); -} - -static void readScaled(uint8_t *data, size_t offset_w, size_t offset_h, const char *file, size_t width, size_t height, Format format) { - if (!file) - return; - - size_t b = formatBytes(format); - - std::unique_ptr input(new uint8_t[b*width*height]); - read(file, input.get(), width, height, format); - - for (size_t h = 0; h < width/2; h++) { - for (size_t w = 0; w < width/2; w++) { - for (size_t c = 0; c < b; c++) { - size_t i = 2*b*(width*h + w) + c; - data[b*(width*(offset_h+h) + offset_w+w) + c] = (input[i] + input[i+b] + input[i+b*width] + input[i+b*width+b])/4; - } - } - } -} - -void mipmap(const char *output, size_t width, size_t height, Format format, const char *nw, const char *ne, const char *sw, const char *se) { - size_t size = formatBytes(format)*width*height; - std::unique_ptr data(new uint8_t[size]); - std::memset(data.get(), 0, size); - - readScaled(data.get(), 0, 0, nw, width, height, format); - readScaled(data.get(), width/2, 0, ne, width, height, format); - readScaled(data.get(), 0, height/2, sw, width, height, format); - readScaled(data.get(), width/2, height/2, se, width, height, format); - - write(output, data.get(), width, height, format); -} - -} -} diff --git a/src/PNG.hpp b/src/PNG.hpp deleted file mode 100644 index fdd2dc0..0000000 --- a/src/PNG.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include - - -namespace MinedMap { -namespace PNG { - -enum Format { - RGB_ALPHA, - GRAY_ALPHA, - GRAY, -}; - -static inline size_t formatBytes(Format format) { - const size_t data[] = { - [RGB_ALPHA] = 4, - [GRAY_ALPHA] = 2, - [GRAY] = 1, - }; - - return data[format]; -} - -void write(const char *filename, const uint8_t *data, size_t width, size_t height, Format format); -void read(const char *filename, uint8_t *data, size_t width, size_t height, Format format); -void mipmap(const char *output, size_t width, size_t height, Format format, const char *nw, const char *ne, const char *sw, const char *se); - -} -} diff --git a/src/Resource/Biome.cpp b/src/Resource/Biome.cpp deleted file mode 100644 index 1ca2114..0000000 --- a/src/Resource/Biome.cpp +++ /dev/null @@ -1,448 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - Copyright (c) 2019, Roman Shishkin - All rights reserved. -*/ - - -#include "Biome.hpp" - -#include "BlockType.hpp" - -namespace MinedMap { -namespace Resource { - -static FloatColor colorFromParams(float temp, float rain, bool grass) { - const FloatColor grassColors[3] = { - {0.502f, 0.706f, 0.592f}, // lower right - {0.247f, 0.012f, -0.259f}, // lower left - lower right - {-0.471f, 0.086f, -0.133f}, // upper left - lower left - }; - const FloatColor foliageColors[3] = { - {0.376f, 0.631f, 0.482f}, // lower right - {0.306f, 0.012f, -0.317f}, // lower left - lower right - {-0.580f, 0.106f, -0.165f}, // upper left - lower left - }; - - const FloatColor *colors = grass ? grassColors : foliageColors; - - return colors[0] + temp*colors[1] + rain*colors[2]; -} - - -FloatColor Biome::getGrassColor(float temp, float rain) const { - return colorFromParams(temp, rain, true); -} - -FloatColor Biome::getFoliageColor(float temp, float rain) const { - return colorFromParams(temp, rain, false); -} - - -FloatColor Biome::getBlockColor(const BlockType *type, y_idx_t height) const { - FloatColor c = { - float(type->color.r), - float(type->color.g), - float(type->color.b), - }; - - float t = clamp(temp - std::max(0.0f, (int(height)-64)/600.0f), 0, 1); - float r = clamp(rain, 0, 1) * t; - - if (type->flags & BLOCK_GRASS) - c *= getGrassColor(t, r); - if (type->flags & BLOCK_FOLIAGE) - c *= getFoliageColor(t, r); - if (type->flags & BLOCK_BIRCH) - c *= FloatColor {0.380f, 0.600f, 0.380f}; - if (type->flags & BLOCK_SPRUCE) - c *= FloatColor {0.502f, 0.655f, 0.333f}; - if (type->flags & BLOCK_WATER) - c *= getWaterColor(); - - float h = 0.5f + height * 0.005f; - - c.r = clamp(c.r * h, 0, 255); - c.g = clamp(c.g * h, 0, 255); - c.b = clamp(c.b * h, 0, 255); - - return c; -} - - -class SwampBiome : public Biome { -protected: - virtual FloatColor getGrassColor(float, float) const { - return {0.417f, 0.439f, 0.224f}; - } - virtual FloatColor getFoliageColor(float temp, float rain) const { - return getGrassColor(temp, rain); - } - -public: - SwampBiome(float temp0, float rain0, FloatColor water0) : - Biome(temp0, rain0, water0) {} -}; - -class DarkForestBiome : public Biome { -private: - const FloatColor darkGreen = {0.157f, 0.204f, 0.039f}; - -protected: - virtual FloatColor getGrassColor(float temp, float rain) const { - return 0.5 * (darkGreen + colorFromParams(temp, rain, true)); - } - - virtual FloatColor getFoliageColor(float temp, float rain) const { - return 0.5 * (darkGreen + colorFromParams(temp, rain, false)); - } - -public: - DarkForestBiome(float temp0, float rain0) : Biome(temp0, rain0) {} -}; - -class BadlandsBiome : public Biome { -protected: - virtual FloatColor getGrassColor(float, float) const { - return {0.565f, 0.506f, 0.302f}; - } - virtual FloatColor getFoliageColor(float, float) const { - return {0.620f, 0.506f, 0.302f}; - } - -public: - BadlandsBiome(float temp0, float rain0) : Biome(temp0, rain0) {} -}; - - -/* Values from https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp or - * extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn */ - -static const Biome BiomeDefault(0.5f, 0.5f); -static const Biome BiomePlains(0.8f, 0.4f); -static const Biome BiomeDesert(2.0f, 0.0f); -static const Biome BiomeMountains(0.2f, 0.3f); -static const Biome BiomeForest(0.7f, 0.8f); -static const Biome BiomeTaiga(0.25f, 0.8f); -static const SwampBiome BiomeSwamp(0.8f, 0.9f, {0.380f, 0.482f, 0.392f}); -static const Biome BiomeFrozen(0.0f, 0.5f); -static const Biome BiomeMushroomFields(0.9f, 1.0f); -static const Biome BiomeJungle(0.95f, 0.9f); -static const Biome BiomeJungleEdge(0.95f, 0.8f); -static const Biome BiomeSnowyBeach(0.05f, 0.3f); -static const Biome BiomeBirchForest(0.6f, 0.6f); -static const DarkForestBiome BiomeDarkForest(0.7f, 0.8f); -static const Biome BiomeSnowyTaiga(-0.5f, 0.4f); -static const Biome BiomeGiantTreeTaiga(0.3f, 0.8f); -static const Biome BiomeSavanna(1.2f, 0.0f); -static const Biome BiomeSavannaPlateau(1.0f, 0.0f); -static const Biome BiomeShatteredSavanna(1.1f, 0.0f); -static const BadlandsBiome BiomeBadlands(2.0f, 0.0f); - -static const Biome BiomeFrozenOcean(0.0f, 0.5f, {0.224f, 0.220f, 0.788f}); -static const Biome BiomeWarmOcean(0.8f, 0.5f, {0.263f, 0.835f, 0.933f}); -static const Biome BiomeLukewarmOcean(0.8f, 0.5f, {0.271f, 0.678f, 0.949f}); -static const Biome BiomeColdOcean(0.8f, 0.5f, {0.239f, 0.341f, 0.839f}); - -static const Biome BiomeMeadow(0.5f, 0.8f); -static const Biome BiomeGrove(-0.2f, 0.8f); -static const Biome BiomeJaggedPeaks(-0.7f, 0.9f); -static const Biome BiomeStonyPeaks(1.0f, 0.3f); -static const Biome BiomeSnowySlopes(-0.3f, 0.9f); -static const SwampBiome BiomeMangroveSwamp(0.8f, 0.9f, {0.227f, 0.478f, 0.416f}); - -const Biome *const Biome::Default = &BiomeDefault; - -/* Minecraft 1.18 does not use numerical IDs for biomes anymore. - * Previously unused biome IDs are assigned to the new biome types of - * Minecraft 1.18 for storage in MinedMap's biome data cache. */ - -const Biome *const Biome::Biomes[256] = { - /* 0 */ &BiomeDefault, /* Ocean */ - /* 1 */ &BiomePlains, - /* 2 */ &BiomeDesert, - /* 3 */ &BiomeMountains, - /* 4 */ &BiomeForest, - /* 5 */ &BiomeTaiga, - /* 6 */ &BiomeSwamp, - /* 7 */ &BiomeDefault, /* River */ - /* 8 */ &BiomeDesert, /* Nether */ - /* 9 */ &BiomeDefault, /* The End */ - /* 10 */ &BiomeFrozenOcean, - /* 11 */ &BiomeFrozenOcean, /* Frozen River */ - /* 12 */ &BiomeFrozen, /* Snowy Tundra */ - /* 13 */ &BiomeFrozen, /* Snowy Mountains */ - /* 14 */ &BiomeMushroomFields, - /* 15 */ &BiomeMushroomFields, /* Mushroom Field Shore */ - /* 16 */ &BiomePlains, /* Beach */ - /* 17 */ &BiomeDesert, /* Desert Hills */ - /* 18 */ &BiomeForest, /* Wooded Hiils */ - /* 19 */ &BiomeTaiga, /* Taiga Hills */ - /* 20 */ &BiomeMountains, /* Moutain Edge */ - /* 21 */ &BiomeJungle, - /* 22 */ &BiomeJungle, /* Jungle Hills */ - /* 23 */ &BiomeJungleEdge, - /* 24 */ &BiomeDefault, /* Deep Ocean */ - /* 25 */ &BiomeMountains, /* Stone Shore */ - /* 26 */ &BiomeSnowyBeach, - /* 27 */ &BiomeBirchForest, - /* 28 */ &BiomeBirchForest, /* Birch Forest Hills */ - /* 29 */ &BiomeDarkForest, - /* 30 */ &BiomeSnowyTaiga, - /* 31 */ &BiomeSnowyTaiga, /* Snowy Taiga Hills */ - /* 32 */ &BiomeGiantTreeTaiga, - /* 33 */ &BiomeGiantTreeTaiga, /* Giant Tree Taiga Hills */ - /* 34 */ &BiomeMountains, /* Wooded Mountains */ - /* 35 */ &BiomeSavanna, - /* 36 */ &BiomeSavanna, /* Savanna Plateau */ - /* 37 */ &BiomeBadlands, - /* 38 */ &BiomeBadlands, /* Wooded Badlands Plateau */ - /* 39 */ &BiomeBadlands, /* Badlands Plateau */ - /* 40 */ &BiomeDefault, /* Small End Islands */ - /* 41 */ &BiomeDefault, /* End Midlands */ - /* 42 */ &BiomeDefault, /* End Highlands */ - /* 43 */ &BiomeDefault, /* End Barrens */ - /* 44 */ &BiomeWarmOcean, - /* 45 */ &BiomeLukewarmOcean, - /* 46 */ &BiomeColdOcean, - /* 47 */ &BiomeWarmOcean, /* Deep Warm Ocean */ - /* 48 */ &BiomeLukewarmOcean, /* Deep Lukewarm Ocean */ - /* 49 */ &BiomeColdOcean, /* Deep Cold Ocean */ - /* 50 */ &BiomeFrozenOcean, /* Deep Frozen Ocean */ - /* 51 */ &BiomeMeadow, /* MinedMap assignment */ - /* 52 */ &BiomeGrove, /* MinedMap assignment */ - /* 53 */ &BiomeJaggedPeaks, /* MinedMap assignment */ - /* 54 */ &BiomeStonyPeaks, /* MinedMap assignment */ - /* 55 */ &BiomeSnowySlopes, /* MinedMap assignment */ - /* 56 */ &BiomeMangroveSwamp, /* MinedMap assignment */ - /* 57 */ nullptr, - /* 58 */ nullptr, - /* 59 */ nullptr, - /* 60 */ nullptr, - /* 61 */ nullptr, - /* 62 */ nullptr, - /* 63 */ nullptr, - /* 64 */ nullptr, - /* 65 */ nullptr, - /* 66 */ nullptr, - /* 67 */ nullptr, - /* 68 */ nullptr, - /* 69 */ nullptr, - /* 70 */ nullptr, - /* 71 */ nullptr, - /* 72 */ nullptr, - /* 73 */ nullptr, - /* 74 */ nullptr, - /* 75 */ nullptr, - /* 76 */ nullptr, - /* 77 */ nullptr, - /* 78 */ nullptr, - /* 79 */ nullptr, - /* 80 */ nullptr, - /* 81 */ nullptr, - /* 82 */ nullptr, - /* 83 */ nullptr, - /* 84 */ nullptr, - /* 85 */ nullptr, - /* 86 */ nullptr, - /* 87 */ nullptr, - /* 88 */ nullptr, - /* 89 */ nullptr, - /* 90 */ nullptr, - /* 91 */ nullptr, - /* 92 */ nullptr, - /* 93 */ nullptr, - /* 94 */ nullptr, - /* 95 */ nullptr, - /* 96 */ nullptr, - /* 97 */ nullptr, - /* 98 */ nullptr, - /* 99 */ nullptr, - /* 100 */ nullptr, - /* 101 */ nullptr, - /* 102 */ nullptr, - /* 103 */ nullptr, - /* 104 */ nullptr, - /* 105 */ nullptr, - /* 106 */ nullptr, - /* 107 */ nullptr, - /* 108 */ nullptr, - /* 109 */ nullptr, - /* 110 */ nullptr, - /* 111 */ nullptr, - /* 112 */ nullptr, - /* 113 */ nullptr, - /* 114 */ nullptr, - /* 115 */ nullptr, - /* 116 */ nullptr, - /* 117 */ nullptr, - /* 118 */ nullptr, - /* 119 */ nullptr, - /* 120 */ nullptr, - /* 121 */ nullptr, - /* 122 */ nullptr, - /* 123 */ nullptr, - /* 124 */ nullptr, - /* 125 */ nullptr, - /* 126 */ nullptr, - /* 127 */ &BiomeDefault, /* The Void */ - /* 128 */ nullptr, - /* 129 */ &BiomeDefault, /* Sunflower Plains */ - /* 130 */ &BiomeDesert, /* Desert Lakes */ - /* 131 */ &BiomeMountains, /* Gravelly Mountains */ - /* 132 */ &BiomeForest, /* Flower Forest */ - /* 133 */ &BiomeTaiga, /* Taiga Mountains */ - /* 134 */ &BiomeSwamp, /* Swamp Hills */ - /* 135 */ nullptr, - /* 136 */ nullptr, - /* 137 */ nullptr, - /* 138 */ nullptr, - /* 139 */ nullptr, - /* 140 */ &BiomeFrozen, /* Ice Spikes */ - /* 141 */ nullptr, - /* 142 */ nullptr, - /* 143 */ nullptr, - /* 144 */ nullptr, - /* 145 */ nullptr, - /* 146 */ nullptr, - /* 147 */ nullptr, - /* 148 */ nullptr, - /* 149 */ &BiomeJungle, /* Modified Jungle */ - /* 150 */ nullptr, - /* 151 */ &BiomeJungleEdge, /* Modified Jungle Edge */ - /* 152 */ nullptr, - /* 153 */ nullptr, - /* 154 */ nullptr, - /* 155 */ &BiomeBirchForest, /* Tall Birch Forest */ - /* 156 */ &BiomeBirchForest, /* Tall Birch Hills */ - /* 157 */ &BiomeDarkForest, /* Dark Forest Hills */ - /* 158 */ &BiomeSnowyTaiga, /* Snowy Taiga Mountains */ - /* 159 */ nullptr, - /* 160 */ &BiomeTaiga, /* Giant Spruce Taiga */ - /* 161 */ &BiomeTaiga, /* Giant Spruce Taiga Hills */ - /* 162 */ &BiomeMountains, /* Gravelly Mountains+ */ - /* 163 */ &BiomeShatteredSavanna, - /* 164 */ &BiomeSavannaPlateau, /* Shattered Savanna Plateau */ - /* 165 */ &BiomeBadlands, /* Eroded Badlands */ - /* 166 */ &BiomeBadlands, /* Modified Wooded Badlands Plateau */ - /* 167 */ &BiomeBadlands, /* Modified Badlands Plateau */ - /* 168 */ &BiomeJungle, /* Bamboo Jungle */ - /* 169 */ &BiomeJungle, /* Bamboo Jungle Hills */ - /* 170 */ &BiomeDesert, /* Soul Sand Valley */ - /* 171 */ &BiomeDesert, /* Crimson Forest */ - /* 172 */ &BiomeDesert, /* Warped Forest */ - /* 173 */ &BiomeDesert, /* Basalt Deltas */ - /* 174 */ &BiomePlains, /* Dripstone Caves */ - /* 175 */ &BiomeDefault, /* Lush Caves */ -}; - -/* It is unclear which of the renamed/merged biome IDs can appear in practice, - * but it shouldn't hurt to support them anyways */ - -const std::unordered_map Biome::Names = { - { "minecraft:badlands", 37 }, - { "minecraft:badlands_plateau", 39 }, /* 1.18: Merged into badlands */ - { "minecraft:bamboo_jungle", 168 }, - { "minecraft:bamboo_jungle_hills", 169 }, /* 1.18: Merged into bamboo_jungle */ - { "minecraft:basalt_deltas", 173 }, - { "minecraft:beach", 16 }, - { "minecraft:birch_forest", 27 }, - { "minecraft:birch_forest_hills", 28 }, /* 1.18: Merged into birch_forest */ - { "minecraft:cold_ocean", 46 }, - { "minecraft:crimson_forest", 171 }, - { "minecraft:dark_forest", 29 }, - { "minecraft:dark_forest_hills", 157 }, /* 1.18: Merged into dark_forest */ - { "minecraft:deep_cold_ocean", 49 }, - { "minecraft:deep_dark", 1 }, - { "minecraft:deep_frozen_ocean", 50 }, - { "minecraft:deep_lukewarm_ocean", 48 }, - { "minecraft:deep_ocean", 24 }, - { "minecraft:deep_warm_ocean", 47 }, /* 1.18: Merged into warm_ocean */ - { "minecraft:desert", 2 }, - { "minecraft:desert_hills", 17 }, /* 1.18: Merged into desert */ - { "minecraft:desert_lakes", 130 }, /* 1.18: Merged into desert */ - { "minecraft:dripstone_caves", 174 }, - { "minecraft:end_barrens", 43 }, - { "minecraft:end_highlands", 42 }, - { "minecraft:end_midlands", 41 }, - { "minecraft:eroded_badlands", 165 }, - { "minecraft:extreme_hills", 3 }, /* 1.18: Renamed to windswept_hills (after rename from mountains) */ - { "minecraft:flower_forest", 132 }, - { "minecraft:forest", 4 }, - { "minecraft:frozen_ocean", 10 }, - { "minecraft:frozen_peaks", 53 }, /* 1.18: New */ - { "minecraft:frozen_river", 11 }, - { "minecraft:giant_spruce_taiga", 160 }, /* 1.18: Renamed to old_growth_spruce_taiga */ - { "minecraft:giant_spruce_taiga_hills", 161 }, /* 1.18: Merged into giant_spruce_taiga */ - { "minecraft:giant_tree_taiga", 32 }, /* 1.18: Renamed to old_growth_pine_taiga */ - { "minecraft:giant_tree_taiga_hills", 33 }, /* 1.18: Merged into giant_tree_taiga */ - { "minecraft:gravelly_mountains", 131 }, /* 1.18: Renamed to windswept_gravelly_hills */ - { "minecraft:grove", 52 }, /* 1.18: New */ - { "minecraft:ice_spikes", 140 }, - { "minecraft:jagged_peaks", 53 }, /* 1.18: New */ - { "minecraft:jungle", 21 }, - { "minecraft:jungle_edge", 23 }, /* 1.18: Renamed to sparse_jungle */ - { "minecraft:jungle_hills", 22 }, /* 1.18: Merged into jungle */ - { "minecraft:lukewarm_ocean", 45 }, - { "minecraft:lush_caves", 175 }, - { "minecraft:mangrove_swamp", 56 }, - { "minecraft:meadow", 51 }, /* 1.18: New */ - { "minecraft:modified_badlands_plateau", 167 }, /* 1.18: Merged into badlands */ - { "minecraft:modified_gravelly_mountains", 162 }, /* 1.18: Merged into gravelly_mountains */ - { "minecraft:modified_jungle", 149 }, /* 1.18: Merged into jungle */ - { "minecraft:modified_jungle_edge", 151 }, /* 1.18: Merged into jungle_edge */ - { "minecraft:modified_wooded_badlands_plateau", 166 }, /* 1.18: Merged into wooded_badlands */ - { "minecraft:mountain_edge", 20 }, /* 1.18: Merged into mountains */ - { "minecraft:mountains", 3 }, /* 1.18: Renamed to windswept_hills */ - { "minecraft:mushroom_field_shore", 15 }, /* 1.18: Merged into mushroom_fields */ - { "minecraft:mushroom_fields", 14 }, - { "minecraft:nether_wastes", 8 }, - { "minecraft:ocean", 0 }, - { "minecraft:old_growth_birch_forest", 155 }, - { "minecraft:old_growth_pine_taiga", 32 }, - { "minecraft:old_growth_spruce_taiga", 160 }, - { "minecraft:plains", 1 }, - { "minecraft:river", 7 }, - { "minecraft:savanna", 35 }, - { "minecraft:savanna_plateau", 36 }, - { "minecraft:shattered_savanna", 163 }, - { "minecraft:shattered_savanna_plateau", 164 }, /* 1.18: Merged into shattered_savanna */ - { "minecraft:small_end_islands", 40 }, - { "minecraft:snowy_beach", 26 }, - { "minecraft:snowy_mountains", 13 }, /* 1.18: Merged into snowy_tundra */ - { "minecraft:snowy_plains", 12 }, - { "minecraft:snowy_slopes", 55 }, - { "minecraft:snowy_taiga", 30 }, - { "minecraft:snowy_taiga_hills", 31 }, /* 1.18: Merged into snowy_taiga */ - { "minecraft:snowy_taiga_mountains", 158 }, /* 1.18: Merged into snowy_taiga */ - { "minecraft:snowy_tundra", 12 }, - { "minecraft:soul_sand_valley", 170 }, - { "minecraft:sparse_jungle", 23 }, - { "minecraft:stone_shore", 25 }, - { "minecraft:stony_peaks", 54 }, /* 1.18: New */ - { "minecraft:stony_shore", 25 }, - { "minecraft:sunflower_plains", 129 }, - { "minecraft:swamp", 6 }, - { "minecraft:swamp_hills", 134 }, /* 1.18: Merged into swamp */ - { "minecraft:taiga", 5 }, - { "minecraft:taiga_hills", 19 }, /* 1.18: Merged into taiga */ - { "minecraft:taiga_mountains", 133 }, /* 1.18: Merged into taiga */ - { "minecraft:tall_birch_forest", 155 }, /* 1.18: Renamed to old_growth_birch_forest */ - { "minecraft:tall_birch_hills", 156 }, /* 1.18: Merged into tall_birch_forest */ - { "minecraft:the_end", 9 }, - { "minecraft:the_void", 127 }, - { "minecraft:warm_ocean", 44 }, - { "minecraft:warped_forest", 172 }, - { "minecraft:windswept_forest", 34 }, - { "minecraft:windswept_gravelly_hills", 131 }, - { "minecraft:windswept_hills", 3 }, - { "minecraft:windswept_savanna", 163 }, - { "minecraft:wooded_badlands", 38 }, - { "minecraft:wooded_badlands_plateau", 38 }, /* 1.18: Renamed to wooded_badlands */ - { "minecraft:wooded_hills", 18 }, /* 1.18: Merged into forest */ - { "minecraft:wooded_mountains", 34 /* 1.18: Renamed to windswept_forest */}, -}; - -} -} diff --git a/src/Resource/Biome.hpp b/src/Resource/Biome.hpp deleted file mode 100644 index 0cb4f8c..0000000 --- a/src/Resource/Biome.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Color.hpp" -#include "../Util.hpp" - -#include - -namespace MinedMap { -namespace Resource { - -class BlockType; - -class Biome { -private: - float temp, rain; - FloatColor water; - -protected: - virtual FloatColor getGrassColor(float temp, float rain) const; - virtual FloatColor getFoliageColor(float temp, float rain) const; - - FloatColor getWaterColor() const { return water; }; - -public: - static const Biome *const Default; - static const Biome *const Biomes[256]; - static const std::unordered_map Names; - - Biome(float temp0, float rain0, FloatColor water0 = {0.247f, 0.463f, 0.894f}) - : temp(temp0), rain(rain0), water(water0) {} - - FloatColor getBlockColor(const BlockType *type, y_idx_t height) const; -}; - -} -} diff --git a/src/Resource/BlockType.cpp b/src/Resource/BlockType.cpp deleted file mode 100644 index cc76cff..0000000 --- a/src/Resource/BlockType.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2018, Matthias Schiffer - All rights reserved. -*/ - - -#include "BlockType.hpp" - - -namespace MinedMap { -namespace Resource { - -const std::unordered_map BlockType::Types = { - -#include "BlockType.inc.cpp" - -}; - -struct LegacyBlockType { - const char *data[16]; -}; - -static constexpr LegacyBlockType simple(const char *t) { - return { - t, t, t, t, - t, t, t, t, - t, t, t, t, - t, t, t, t, - }; -} - -static const LegacyBlockType LEGACY_BLOCK_TYPE_DATA[256] = { - -#include "LegacyBlockType.inc.cpp" - -}; - - -const BlockType * BlockType::lookup(const std::string &name) { - auto it = Types.find(name); - if (it == Types.end()) - return nullptr; - - return &it->second; -} - -static LegacyPalette makeLegacyPalette() { - const std::string name_prefix("minecraft:"); - - LegacyPalette palette = {}; - for (size_t type = 0; type < 256; type++) { - for (size_t data = 0; data < 16; data++) { - const char *name = LEGACY_BLOCK_TYPE_DATA[type].data[data]; - if (!name) - continue; - - palette.types[type][data] = BlockType::lookup(name_prefix + name); - } - } - - return palette; -} - -const LegacyPalette LEGACY_BLOCK_TYPES = makeLegacyPalette(); - -} -} diff --git a/src/Resource/BlockType.hpp b/src/Resource/BlockType.hpp deleted file mode 100644 index 6861448..0000000 --- a/src/Resource/BlockType.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include -#include - -namespace MinedMap { -namespace Resource { - -#define BLOCK_OPAQUE (1u << 0) -#define BLOCK_GRASS (1u << 1) -#define BLOCK_FOLIAGE (1u << 2) -#define BLOCK_BIRCH (1u << 3) -#define BLOCK_SPRUCE (1u << 4) -#define BLOCK_WATER (1u << 5) - -class BlockType { -private: - static const std::unordered_map Types; - -public: - static const BlockType * lookup(const std::string &name); - - uint8_t flags; - struct { - uint8_t r, g, b; - } color; -}; - - -struct LegacyPalette { - const BlockType *types[256][16]; -}; - -extern const LegacyPalette LEGACY_BLOCK_TYPES; - -} -} diff --git a/src/Resource/BlockType.inc.cpp b/src/Resource/BlockType.inc.cpp deleted file mode 100644 index bc6c087..0000000 --- a/src/Resource/BlockType.inc.cpp +++ /dev/null @@ -1,938 +0,0 @@ -{"minecraft:acacia_button", {0, {0, 0, 0}}}, -{"minecraft:acacia_door", {BLOCK_OPAQUE, {167, 95, 60}}}, -{"minecraft:acacia_fence", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_fence_gate", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {149, 148, 148}}}, -{"minecraft:acacia_log", {BLOCK_OPAQUE, {150, 88, 55}}}, -{"minecraft:acacia_planks", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_pressure_plate", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_sapling", {BLOCK_OPAQUE, {118, 117, 23}}}, -{"minecraft:acacia_sign", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_slab", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_stairs", {BLOCK_OPAQUE, {168, 90, 50}}}, -{"minecraft:acacia_trapdoor", {BLOCK_OPAQUE, {156, 87, 51}}}, -{"minecraft:acacia_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:acacia_wood", {BLOCK_OPAQUE, {103, 96, 86}}}, -{"minecraft:activator_rail", {BLOCK_OPAQUE, {115, 87, 74}}}, -{"minecraft:air", {0, {0, 0, 0}}}, -{"minecraft:allium", {0, {0, 0, 0}}}, -{"minecraft:amethyst_block", {BLOCK_OPAQUE, {133, 97, 191}}}, -{"minecraft:amethyst_cluster", {BLOCK_OPAQUE, {163, 126, 207}}}, -{"minecraft:ancient_debris", {BLOCK_OPAQUE, {94, 66, 58}}}, -{"minecraft:andesite", {BLOCK_OPAQUE, {136, 136, 136}}}, -{"minecraft:andesite_slab", {BLOCK_OPAQUE, {136, 136, 136}}}, -{"minecraft:andesite_stairs", {BLOCK_OPAQUE, {136, 136, 136}}}, -{"minecraft:andesite_wall", {BLOCK_OPAQUE, {136, 136, 136}}}, -{"minecraft:anvil", {BLOCK_OPAQUE, {72, 72, 72}}}, -{"minecraft:attached_melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {141, 142, 141}}}, -{"minecraft:attached_pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {139, 139, 139}}}, -{"minecraft:azalea", {BLOCK_OPAQUE, {101, 124, 47}}}, -{"minecraft:azalea_leaves", {BLOCK_OPAQUE, {90, 114, 44}}}, -{"minecraft:azure_bluet", {0, {0, 0, 0}}}, -{"minecraft:bamboo", {BLOCK_OPAQUE, {93, 144, 19}}}, -{"minecraft:bamboo_sapling", {0, {0, 0, 0}}}, -{"minecraft:barrel", {BLOCK_OPAQUE, {134, 100, 58}}}, -{"minecraft:barrier", {0, {0, 0, 0}}}, -{"minecraft:basalt", {BLOCK_OPAQUE, {80, 81, 86}}}, -{"minecraft:beacon", {BLOCK_OPAQUE, {117, 220, 215}}}, -{"minecraft:bedrock", {BLOCK_OPAQUE, {85, 85, 85}}}, -{"minecraft:bee_nest", {BLOCK_OPAQUE, {202, 160, 74}}}, -{"minecraft:beehive", {BLOCK_OPAQUE, {180, 146, 90}}}, -{"minecraft:beetroots", {BLOCK_OPAQUE, {93, 91, 30}}}, -{"minecraft:bell", {BLOCK_OPAQUE, {253, 235, 110}}}, -{"minecraft:big_dripleaf", {BLOCK_OPAQUE, {111, 141, 51}}}, -{"minecraft:big_dripleaf_stem", {0, {0, 0, 0}}}, -{"minecraft:birch_button", {0, {0, 0, 0}}}, -{"minecraft:birch_door", {BLOCK_OPAQUE, {220, 209, 176}}}, -{"minecraft:birch_fence", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_fence_gate", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_leaves", {BLOCK_OPAQUE|BLOCK_BIRCH, {130, 129, 130}}}, -{"minecraft:birch_log", {BLOCK_OPAQUE, {193, 179, 135}}}, -{"minecraft:birch_planks", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_pressure_plate", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_sapling", {BLOCK_OPAQUE, {127, 160, 79}}}, -{"minecraft:birch_sign", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_slab", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_stairs", {BLOCK_OPAQUE, {192, 175, 121}}}, -{"minecraft:birch_trapdoor", {BLOCK_OPAQUE, {207, 194, 157}}}, -{"minecraft:birch_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:birch_wood", {BLOCK_OPAQUE, {216, 215, 210}}}, -{"minecraft:black_banner", {0, {0, 0, 0}}}, -{"minecraft:black_bed", {0, {0, 0, 0}}}, -{"minecraft:black_candle", {0, {0, 0, 0}}}, -{"minecraft:black_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:black_carpet", {BLOCK_OPAQUE, {20, 21, 25}}}, -{"minecraft:black_concrete", {BLOCK_OPAQUE, {8, 10, 15}}}, -{"minecraft:black_concrete_powder", {BLOCK_OPAQUE, {25, 26, 31}}}, -{"minecraft:black_glazed_terracotta", {BLOCK_OPAQUE, {67, 30, 32}}}, -{"minecraft:black_shulker_box", {BLOCK_OPAQUE, {25, 25, 29}}}, -{"minecraft:black_stained_glass", {BLOCK_OPAQUE, {25, 25, 25}}}, -{"minecraft:black_stained_glass_pane", {BLOCK_OPAQUE, {24, 24, 24}}}, -{"minecraft:black_terracotta", {BLOCK_OPAQUE, {37, 22, 16}}}, -{"minecraft:black_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:black_wool", {BLOCK_OPAQUE, {20, 21, 25}}}, -{"minecraft:blackstone", {BLOCK_OPAQUE, {42, 36, 41}}}, -{"minecraft:blackstone_slab", {BLOCK_OPAQUE, {42, 36, 41}}}, -{"minecraft:blackstone_stairs", {BLOCK_OPAQUE, {42, 36, 41}}}, -{"minecraft:blackstone_wall", {BLOCK_OPAQUE, {42, 36, 41}}}, -{"minecraft:blast_furnace", {BLOCK_OPAQUE, {80, 80, 81}}}, -{"minecraft:blue_banner", {0, {0, 0, 0}}}, -{"minecraft:blue_bed", {0, {0, 0, 0}}}, -{"minecraft:blue_candle", {0, {0, 0, 0}}}, -{"minecraft:blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:blue_carpet", {BLOCK_OPAQUE, {53, 57, 157}}}, -{"minecraft:blue_concrete", {BLOCK_OPAQUE, {44, 46, 143}}}, -{"minecraft:blue_concrete_powder", {BLOCK_OPAQUE, {70, 73, 166}}}, -{"minecraft:blue_glazed_terracotta", {BLOCK_OPAQUE, {47, 64, 139}}}, -{"minecraft:blue_ice", {BLOCK_OPAQUE, {116, 167, 253}}}, -{"minecraft:blue_orchid", {0, {0, 0, 0}}}, -{"minecraft:blue_shulker_box", {BLOCK_OPAQUE, {43, 45, 140}}}, -{"minecraft:blue_stained_glass", {BLOCK_OPAQUE, {51, 76, 178}}}, -{"minecraft:blue_stained_glass_pane", {BLOCK_OPAQUE, {48, 73, 171}}}, -{"minecraft:blue_terracotta", {BLOCK_OPAQUE, {74, 59, 91}}}, -{"minecraft:blue_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:blue_wool", {BLOCK_OPAQUE, {53, 57, 157}}}, -{"minecraft:bone_block", {BLOCK_OPAQUE, {209, 206, 179}}}, -{"minecraft:bookshelf", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:brain_coral", {0, {0, 0, 0}}}, -{"minecraft:brain_coral_block", {BLOCK_OPAQUE, {207, 91, 159}}}, -{"minecraft:brain_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:brain_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:brewing_stand", {BLOCK_OPAQUE, {122, 100, 80}}}, -{"minecraft:brick_slab", {BLOCK_OPAQUE, {150, 97, 83}}}, -{"minecraft:brick_stairs", {BLOCK_OPAQUE, {150, 97, 83}}}, -{"minecraft:brick_wall", {BLOCK_OPAQUE, {150, 97, 83}}}, -{"minecraft:bricks", {BLOCK_OPAQUE, {150, 97, 83}}}, -{"minecraft:brown_banner", {0, {0, 0, 0}}}, -{"minecraft:brown_bed", {0, {0, 0, 0}}}, -{"minecraft:brown_candle", {0, {0, 0, 0}}}, -{"minecraft:brown_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:brown_carpet", {BLOCK_OPAQUE, {114, 71, 40}}}, -{"minecraft:brown_concrete", {BLOCK_OPAQUE, {96, 59, 31}}}, -{"minecraft:brown_concrete_powder", {BLOCK_OPAQUE, {125, 84, 53}}}, -{"minecraft:brown_glazed_terracotta", {BLOCK_OPAQUE, {119, 106, 85}}}, -{"minecraft:brown_mushroom", {0, {0, 0, 0}}}, -{"minecraft:brown_mushroom_block", {BLOCK_OPAQUE, {149, 111, 81}}}, -{"minecraft:brown_shulker_box", {BLOCK_OPAQUE, {106, 66, 35}}}, -{"minecraft:brown_stained_glass", {BLOCK_OPAQUE, {102, 76, 51}}}, -{"minecraft:brown_stained_glass_pane", {BLOCK_OPAQUE, {97, 73, 48}}}, -{"minecraft:brown_terracotta", {BLOCK_OPAQUE, {77, 51, 35}}}, -{"minecraft:brown_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:brown_wool", {BLOCK_OPAQUE, {114, 71, 40}}}, -{"minecraft:bubble_column", {BLOCK_OPAQUE|BLOCK_WATER, {177, 177, 177}}}, -{"minecraft:bubble_coral", {0, {0, 0, 0}}}, -{"minecraft:bubble_coral_block", {BLOCK_OPAQUE, {165, 26, 162}}}, -{"minecraft:bubble_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:bubble_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:budding_amethyst", {BLOCK_OPAQUE, {132, 96, 186}}}, -{"minecraft:cactus", {BLOCK_OPAQUE, {85, 127, 43}}}, -{"minecraft:cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:calcite", {BLOCK_OPAQUE, {223, 224, 220}}}, -{"minecraft:campfire", {BLOCK_OPAQUE, {110, 88, 54}}}, -{"minecraft:candle", {0, {0, 0, 0}}}, -{"minecraft:candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:carrots", {BLOCK_OPAQUE, {81, 124, 37}}}, -{"minecraft:cartography_table", {BLOCK_OPAQUE, {103, 87, 67}}}, -{"minecraft:carved_pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}}, -{"minecraft:cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, -{"minecraft:cave_air", {0, {0, 0, 0}}}, -{"minecraft:cave_vines", {BLOCK_OPAQUE, {90, 109, 40}}}, -{"minecraft:cave_vines_plant", {BLOCK_OPAQUE, {88, 101, 38}}}, -{"minecraft:chain", {0, {0, 0, 0}}}, -{"minecraft:chain_command_block", {BLOCK_OPAQUE, {131, 161, 147}}}, -{"minecraft:chest", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:chipped_anvil", {BLOCK_OPAQUE, {72, 72, 72}}}, -{"minecraft:chiseled_deepslate", {BLOCK_OPAQUE, {54, 54, 54}}}, -{"minecraft:chiseled_nether_bricks", {BLOCK_OPAQUE, {47, 23, 28}}}, -{"minecraft:chiseled_polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:chiseled_quartz_block", {BLOCK_OPAQUE, {231, 226, 218}}}, -{"minecraft:chiseled_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:chiseled_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:chiseled_stone_bricks", {BLOCK_OPAQUE, {119, 118, 119}}}, -{"minecraft:chorus_flower", {BLOCK_OPAQUE, {151, 120, 151}}}, -{"minecraft:chorus_plant", {BLOCK_OPAQUE, {93, 57, 93}}}, -{"minecraft:clay", {BLOCK_OPAQUE, {160, 166, 179}}}, -{"minecraft:coal_block", {BLOCK_OPAQUE, {16, 15, 15}}}, -{"minecraft:coal_ore", {BLOCK_OPAQUE, {105, 105, 105}}}, -{"minecraft:coarse_dirt", {BLOCK_OPAQUE, {119, 85, 59}}}, -{"minecraft:cobbled_deepslate", {BLOCK_OPAQUE, {77, 77, 80}}}, -{"minecraft:cobbled_deepslate_slab", {BLOCK_OPAQUE, {77, 77, 80}}}, -{"minecraft:cobbled_deepslate_stairs", {BLOCK_OPAQUE, {77, 77, 80}}}, -{"minecraft:cobbled_deepslate_wall", {BLOCK_OPAQUE, {77, 77, 80}}}, -{"minecraft:cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}}, -{"minecraft:cobblestone_slab", {BLOCK_OPAQUE, {127, 127, 127}}}, -{"minecraft:cobblestone_stairs", {BLOCK_OPAQUE, {127, 127, 127}}}, -{"minecraft:cobblestone_wall", {BLOCK_OPAQUE, {127, 127, 127}}}, -{"minecraft:cobweb", {BLOCK_OPAQUE, {228, 233, 234}}}, -{"minecraft:cocoa", {BLOCK_OPAQUE, {154, 91, 40}}}, -{"minecraft:command_block", {BLOCK_OPAQUE, {181, 136, 108}}}, -{"minecraft:comparator", {BLOCK_OPAQUE, {166, 161, 159}}}, -{"minecraft:composter", {BLOCK_OPAQUE, {88, 61, 23}}}, -{"minecraft:conduit", {BLOCK_OPAQUE, {159, 139, 113}}}, -{"minecraft:copper_block", {BLOCK_OPAQUE, {192, 107, 79}}}, -{"minecraft:copper_ore", {BLOCK_OPAQUE, {124, 125, 120}}}, -{"minecraft:cornflower", {0, {0, 0, 0}}}, -{"minecraft:cracked_deepslate_bricks", {BLOCK_OPAQUE, {64, 64, 65}}}, -{"minecraft:cracked_deepslate_tiles", {BLOCK_OPAQUE, {52, 52, 52}}}, -{"minecraft:cracked_nether_bricks", {BLOCK_OPAQUE, {40, 20, 23}}}, -{"minecraft:cracked_polished_blackstone_bricks", {BLOCK_OPAQUE, {44, 37, 43}}}, -{"minecraft:cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}}, -{"minecraft:crafting_table", {BLOCK_OPAQUE, {119, 73, 42}}}, -{"minecraft:creeper_head", {0, {0, 0, 0}}}, -{"minecraft:creeper_wall_head", {0, {0, 0, 0}}}, -{"minecraft:crimson_button", {0, {0, 0, 0}}}, -{"minecraft:crimson_door", {BLOCK_OPAQUE, {114, 54, 79}}}, -{"minecraft:crimson_fence", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_fence_gate", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_fungus", {0, {0, 0, 0}}}, -{"minecraft:crimson_hyphae", {BLOCK_OPAQUE, {92, 25, 29}}}, -{"minecraft:crimson_nylium", {BLOCK_OPAQUE, {130, 31, 31}}}, -{"minecraft:crimson_planks", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_pressure_plate", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_roots", {BLOCK_OPAQUE, {126, 8, 41}}}, -{"minecraft:crimson_sign", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_slab", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_stairs", {BLOCK_OPAQUE, {101, 48, 70}}}, -{"minecraft:crimson_stem", {BLOCK_OPAQUE, {112, 49, 70}}}, -{"minecraft:crimson_trapdoor", {BLOCK_OPAQUE, {103, 50, 72}}}, -{"minecraft:crimson_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:crying_obsidian", {BLOCK_OPAQUE, {32, 10, 60}}}, -{"minecraft:cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:cut_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:cut_red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:cut_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:cut_sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:cyan_banner", {0, {0, 0, 0}}}, -{"minecraft:cyan_bed", {0, {0, 0, 0}}}, -{"minecraft:cyan_candle", {0, {0, 0, 0}}}, -{"minecraft:cyan_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:cyan_carpet", {BLOCK_OPAQUE, {21, 137, 145}}}, -{"minecraft:cyan_concrete", {BLOCK_OPAQUE, {21, 119, 136}}}, -{"minecraft:cyan_concrete_powder", {BLOCK_OPAQUE, {36, 147, 157}}}, -{"minecraft:cyan_glazed_terracotta", {BLOCK_OPAQUE, {52, 118, 125}}}, -{"minecraft:cyan_shulker_box", {BLOCK_OPAQUE, {20, 121, 135}}}, -{"minecraft:cyan_stained_glass", {BLOCK_OPAQUE, {76, 127, 153}}}, -{"minecraft:cyan_stained_glass_pane", {BLOCK_OPAQUE, {73, 122, 147}}}, -{"minecraft:cyan_terracotta", {BLOCK_OPAQUE, {86, 91, 91}}}, -{"minecraft:cyan_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:cyan_wool", {BLOCK_OPAQUE, {21, 137, 145}}}, -{"minecraft:damaged_anvil", {BLOCK_OPAQUE, {72, 72, 72}}}, -{"minecraft:dandelion", {0, {0, 0, 0}}}, -{"minecraft:dark_oak_button", {0, {0, 0, 0}}}, -{"minecraft:dark_oak_door", {BLOCK_OPAQUE, {76, 51, 25}}}, -{"minecraft:dark_oak_fence", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_fence_gate", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {150, 150, 150}}}, -{"minecraft:dark_oak_log", {BLOCK_OPAQUE, {67, 45, 22}}}, -{"minecraft:dark_oak_planks", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_pressure_plate", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}}, -{"minecraft:dark_oak_sign", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_slab", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_stairs", {BLOCK_OPAQUE, {66, 43, 20}}}, -{"minecraft:dark_oak_trapdoor", {BLOCK_OPAQUE, {75, 49, 23}}}, -{"minecraft:dark_oak_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:dark_oak_wood", {BLOCK_OPAQUE, {60, 46, 26}}}, -{"minecraft:dark_prismarine", {BLOCK_OPAQUE, {51, 91, 75}}}, -{"minecraft:dark_prismarine_slab", {BLOCK_OPAQUE, {51, 91, 75}}}, -{"minecraft:dark_prismarine_stairs", {BLOCK_OPAQUE, {51, 91, 75}}}, -{"minecraft:daylight_detector", {BLOCK_OPAQUE, {130, 116, 94}}}, -{"minecraft:dead_brain_coral", {0, {0, 0, 0}}}, -{"minecraft:dead_brain_coral_block", {BLOCK_OPAQUE, {124, 117, 114}}}, -{"minecraft:dead_brain_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_brain_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_bubble_coral", {0, {0, 0, 0}}}, -{"minecraft:dead_bubble_coral_block", {BLOCK_OPAQUE, {131, 123, 119}}}, -{"minecraft:dead_bubble_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_bubble_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_bush", {BLOCK_OPAQUE, {107, 78, 40}}}, -{"minecraft:dead_fire_coral", {0, {0, 0, 0}}}, -{"minecraft:dead_fire_coral_block", {BLOCK_OPAQUE, {131, 123, 119}}}, -{"minecraft:dead_fire_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_fire_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_horn_coral", {0, {0, 0, 0}}}, -{"minecraft:dead_horn_coral_block", {BLOCK_OPAQUE, {133, 126, 122}}}, -{"minecraft:dead_horn_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_horn_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_tube_coral", {0, {0, 0, 0}}}, -{"minecraft:dead_tube_coral_block", {BLOCK_OPAQUE, {130, 123, 119}}}, -{"minecraft:dead_tube_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:dead_tube_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:deepslate", {BLOCK_OPAQUE, {80, 80, 82}}}, -{"minecraft:deepslate_brick_slab", {BLOCK_OPAQUE, {70, 70, 71}}}, -{"minecraft:deepslate_brick_stairs", {BLOCK_OPAQUE, {70, 70, 71}}}, -{"minecraft:deepslate_brick_wall", {BLOCK_OPAQUE, {70, 70, 71}}}, -{"minecraft:deepslate_bricks", {BLOCK_OPAQUE, {70, 70, 71}}}, -{"minecraft:deepslate_coal_ore", {BLOCK_OPAQUE, {74, 74, 76}}}, -{"minecraft:deepslate_copper_ore", {BLOCK_OPAQUE, {92, 93, 89}}}, -{"minecraft:deepslate_diamond_ore", {BLOCK_OPAQUE, {83, 106, 106}}}, -{"minecraft:deepslate_emerald_ore", {BLOCK_OPAQUE, {78, 104, 87}}}, -{"minecraft:deepslate_gold_ore", {BLOCK_OPAQUE, {115, 102, 78}}}, -{"minecraft:deepslate_iron_ore", {BLOCK_OPAQUE, {106, 99, 94}}}, -{"minecraft:deepslate_lapis_ore", {BLOCK_OPAQUE, {79, 90, 115}}}, -{"minecraft:deepslate_redstone_ore", {BLOCK_OPAQUE, {104, 73, 74}}}, -{"minecraft:deepslate_tile_slab", {BLOCK_OPAQUE, {54, 54, 55}}}, -{"minecraft:deepslate_tile_stairs", {BLOCK_OPAQUE, {54, 54, 55}}}, -{"minecraft:deepslate_tile_wall", {BLOCK_OPAQUE, {54, 54, 55}}}, -{"minecraft:deepslate_tiles", {BLOCK_OPAQUE, {54, 54, 55}}}, -{"minecraft:detector_rail", {BLOCK_OPAQUE, {123, 104, 90}}}, -{"minecraft:diamond_block", {BLOCK_OPAQUE, {98, 237, 228}}}, -{"minecraft:diamond_ore", {BLOCK_OPAQUE, {121, 141, 140}}}, -{"minecraft:diorite", {BLOCK_OPAQUE, {188, 188, 188}}}, -{"minecraft:diorite_slab", {BLOCK_OPAQUE, {188, 188, 188}}}, -{"minecraft:diorite_stairs", {BLOCK_OPAQUE, {188, 188, 188}}}, -{"minecraft:diorite_wall", {BLOCK_OPAQUE, {188, 188, 188}}}, -{"minecraft:dirt", {BLOCK_OPAQUE, {134, 96, 67}}}, -{"minecraft:dirt_path", {BLOCK_OPAQUE, {148, 121, 65}}}, -{"minecraft:dispenser", {BLOCK_OPAQUE, {110, 109, 109}}}, -{"minecraft:dragon_egg", {BLOCK_OPAQUE, {12, 9, 15}}}, -{"minecraft:dragon_head", {0, {0, 0, 0}}}, -{"minecraft:dragon_wall_head", {0, {0, 0, 0}}}, -{"minecraft:dried_kelp_block", {BLOCK_OPAQUE, {50, 58, 38}}}, -{"minecraft:dripstone_block", {BLOCK_OPAQUE, {134, 107, 92}}}, -{"minecraft:dropper", {BLOCK_OPAQUE, {110, 109, 109}}}, -{"minecraft:emerald_block", {BLOCK_OPAQUE, {42, 203, 87}}}, -{"minecraft:emerald_ore", {BLOCK_OPAQUE, {108, 136, 115}}}, -{"minecraft:enchanting_table", {BLOCK_OPAQUE, {128, 75, 85}}}, -{"minecraft:end_gateway", {BLOCK_OPAQUE, {15, 10, 24}}}, -{"minecraft:end_portal", {BLOCK_OPAQUE, {15, 10, 24}}}, -{"minecraft:end_portal_frame", {BLOCK_OPAQUE, {91, 120, 97}}}, -{"minecraft:end_rod", {0, {0, 0, 0}}}, -{"minecraft:end_stone", {BLOCK_OPAQUE, {219, 222, 158}}}, -{"minecraft:end_stone_brick_slab", {BLOCK_OPAQUE, {218, 224, 162}}}, -{"minecraft:end_stone_brick_stairs", {BLOCK_OPAQUE, {218, 224, 162}}}, -{"minecraft:end_stone_brick_wall", {BLOCK_OPAQUE, {218, 224, 162}}}, -{"minecraft:end_stone_bricks", {BLOCK_OPAQUE, {218, 224, 162}}}, -{"minecraft:ender_chest", {BLOCK_OPAQUE, {15, 10, 24}}}, -{"minecraft:exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}}, -{"minecraft:exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:farmland", {BLOCK_OPAQUE, {81, 44, 15}}}, -{"minecraft:fern", {0, {0, 0, 0}}}, -{"minecraft:fire", {BLOCK_OPAQUE, {211, 140, 53}}}, -{"minecraft:fire_coral", {0, {0, 0, 0}}}, -{"minecraft:fire_coral_block", {BLOCK_OPAQUE, {163, 35, 46}}}, -{"minecraft:fire_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:fire_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:fletching_table", {BLOCK_OPAQUE, {197, 180, 133}}}, -{"minecraft:flower_pot", {BLOCK_OPAQUE, {124, 68, 53}}}, -{"minecraft:flowering_azalea", {BLOCK_OPAQUE, {112, 121, 64}}}, -{"minecraft:flowering_azalea_leaves", {BLOCK_OPAQUE, {99, 111, 60}}}, -{"minecraft:frogspawn", {BLOCK_OPAQUE, {105, 90, 82}}}, -{"minecraft:frosted_ice", {BLOCK_OPAQUE, {140, 181, 252}}}, -{"minecraft:furnace", {BLOCK_OPAQUE, {110, 109, 109}}}, -{"minecraft:gilded_blackstone", {BLOCK_OPAQUE, {55, 42, 38}}}, -{"minecraft:glass", {BLOCK_OPAQUE, {175, 213, 219}}}, -{"minecraft:glass_pane", {BLOCK_OPAQUE, {170, 210, 217}}}, -{"minecraft:glow_item_frame", {0, {0, 0, 0}}}, -{"minecraft:glow_lichen", {0, {0, 0, 0}}}, -{"minecraft:glowstone", {BLOCK_OPAQUE, {171, 131, 84}}}, -{"minecraft:gold_block", {BLOCK_OPAQUE, {246, 208, 61}}}, -{"minecraft:gold_ore", {BLOCK_OPAQUE, {145, 133, 106}}}, -{"minecraft:granite", {BLOCK_OPAQUE, {149, 103, 85}}}, -{"minecraft:granite_slab", {BLOCK_OPAQUE, {149, 103, 85}}}, -{"minecraft:granite_stairs", {BLOCK_OPAQUE, {149, 103, 85}}}, -{"minecraft:granite_wall", {BLOCK_OPAQUE, {149, 103, 85}}}, -{"minecraft:grass", {0, {0, 0, 0}}}, -{"minecraft:grass_block", {BLOCK_OPAQUE|BLOCK_GRASS, {147, 147, 147}}}, -{"minecraft:grass_path", {BLOCK_OPAQUE, {148, 121, 65}}}, -{"minecraft:gravel", {BLOCK_OPAQUE, {131, 127, 126}}}, -{"minecraft:gray_banner", {0, {0, 0, 0}}}, -{"minecraft:gray_bed", {0, {0, 0, 0}}}, -{"minecraft:gray_candle", {0, {0, 0, 0}}}, -{"minecraft:gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:gray_carpet", {BLOCK_OPAQUE, {62, 68, 71}}}, -{"minecraft:gray_concrete", {BLOCK_OPAQUE, {54, 57, 61}}}, -{"minecraft:gray_concrete_powder", {BLOCK_OPAQUE, {76, 81, 84}}}, -{"minecraft:gray_glazed_terracotta", {BLOCK_OPAQUE, {83, 90, 93}}}, -{"minecraft:gray_shulker_box", {BLOCK_OPAQUE, {55, 58, 62}}}, -{"minecraft:gray_stained_glass", {BLOCK_OPAQUE, {76, 76, 76}}}, -{"minecraft:gray_stained_glass_pane", {BLOCK_OPAQUE, {73, 73, 73}}}, -{"minecraft:gray_terracotta", {BLOCK_OPAQUE, {57, 42, 35}}}, -{"minecraft:gray_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:gray_wool", {BLOCK_OPAQUE, {62, 68, 71}}}, -{"minecraft:green_banner", {0, {0, 0, 0}}}, -{"minecraft:green_bed", {0, {0, 0, 0}}}, -{"minecraft:green_candle", {0, {0, 0, 0}}}, -{"minecraft:green_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:green_carpet", {BLOCK_OPAQUE, {84, 109, 27}}}, -{"minecraft:green_concrete", {BLOCK_OPAQUE, {73, 91, 36}}}, -{"minecraft:green_concrete_powder", {BLOCK_OPAQUE, {97, 119, 44}}}, -{"minecraft:green_glazed_terracotta", {BLOCK_OPAQUE, {117, 142, 67}}}, -{"minecraft:green_shulker_box", {BLOCK_OPAQUE, {79, 100, 31}}}, -{"minecraft:green_stained_glass", {BLOCK_OPAQUE, {102, 127, 51}}}, -{"minecraft:green_stained_glass_pane", {BLOCK_OPAQUE, {97, 122, 48}}}, -{"minecraft:green_terracotta", {BLOCK_OPAQUE, {76, 83, 42}}}, -{"minecraft:green_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:green_wool", {BLOCK_OPAQUE, {84, 109, 27}}}, -{"minecraft:grindstone", {BLOCK_OPAQUE, {142, 142, 142}}}, -{"minecraft:hanging_roots", {BLOCK_OPAQUE, {161, 115, 91}}}, -{"minecraft:hay_block", {BLOCK_OPAQUE, {165, 139, 12}}}, -{"minecraft:heavy_weighted_pressure_plate", {BLOCK_OPAQUE, {220, 220, 220}}}, -{"minecraft:honey_block", {BLOCK_OPAQUE, {251, 185, 52}}}, -{"minecraft:honeycomb_block", {BLOCK_OPAQUE, {229, 148, 29}}}, -{"minecraft:hopper", {BLOCK_OPAQUE, {75, 74, 75}}}, -{"minecraft:horn_coral", {0, {0, 0, 0}}}, -{"minecraft:horn_coral_block", {BLOCK_OPAQUE, {216, 199, 66}}}, -{"minecraft:horn_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:horn_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:ice", {BLOCK_OPAQUE, {145, 183, 253}}}, -{"minecraft:infested_chiseled_stone_bricks", {BLOCK_OPAQUE, {119, 118, 119}}}, -{"minecraft:infested_cobblestone", {BLOCK_OPAQUE, {127, 127, 127}}}, -{"minecraft:infested_cracked_stone_bricks", {BLOCK_OPAQUE, {118, 117, 118}}}, -{"minecraft:infested_deepslate", {BLOCK_OPAQUE, {80, 80, 82}}}, -{"minecraft:infested_mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}}, -{"minecraft:infested_stone", {BLOCK_OPAQUE, {125, 125, 125}}}, -{"minecraft:infested_stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}}, -{"minecraft:iron_bars", {BLOCK_OPAQUE, {136, 139, 135}}}, -{"minecraft:iron_block", {BLOCK_OPAQUE, {220, 220, 220}}}, -{"minecraft:iron_door", {BLOCK_OPAQUE, {194, 193, 193}}}, -{"minecraft:iron_ore", {BLOCK_OPAQUE, {136, 129, 122}}}, -{"minecraft:iron_trapdoor", {BLOCK_OPAQUE, {202, 202, 202}}}, -{"minecraft:item_frame", {0, {0, 0, 0}}}, -{"minecraft:jack_o_lantern", {BLOCK_OPAQUE, {214, 152, 52}}}, -{"minecraft:jigsaw", {BLOCK_OPAQUE, {80, 69, 81}}}, -{"minecraft:jukebox", {BLOCK_OPAQUE, {93, 64, 47}}}, -{"minecraft:jungle_button", {0, {0, 0, 0}}}, -{"minecraft:jungle_door", {BLOCK_OPAQUE, {163, 119, 84}}}, -{"minecraft:jungle_fence", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_fence_gate", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {156, 154, 143}}}, -{"minecraft:jungle_log", {BLOCK_OPAQUE, {149, 109, 70}}}, -{"minecraft:jungle_planks", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_pressure_plate", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}}, -{"minecraft:jungle_sign", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_slab", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_stairs", {BLOCK_OPAQUE, {160, 115, 80}}}, -{"minecraft:jungle_trapdoor", {BLOCK_OPAQUE, {152, 110, 77}}}, -{"minecraft:jungle_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:jungle_wood", {BLOCK_OPAQUE, {85, 67, 25}}}, -{"minecraft:kelp", {0, {0, 0, 0}}}, -{"minecraft:kelp_plant", {BLOCK_OPAQUE, {86, 130, 42}}}, -{"minecraft:ladder", {0, {0, 0, 0}}}, -{"minecraft:lantern", {BLOCK_OPAQUE, {106, 91, 83}}}, -{"minecraft:lapis_block", {BLOCK_OPAQUE, {30, 67, 140}}}, -{"minecraft:lapis_ore", {BLOCK_OPAQUE, {107, 117, 141}}}, -{"minecraft:large_amethyst_bud", {0, {0, 0, 0}}}, -{"minecraft:large_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {125, 125, 125}}}, -{"minecraft:lava", {BLOCK_OPAQUE, {212, 90, 18}}}, -{"minecraft:lava_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, -{"minecraft:lectern", {BLOCK_OPAQUE, {173, 137, 83}}}, -{"minecraft:lever", {0, {0, 0, 0}}}, -{"minecraft:light", {0, {0, 0, 0}}}, -{"minecraft:light_blue_banner", {0, {0, 0, 0}}}, -{"minecraft:light_blue_bed", {0, {0, 0, 0}}}, -{"minecraft:light_blue_candle", {0, {0, 0, 0}}}, -{"minecraft:light_blue_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:light_blue_carpet", {BLOCK_OPAQUE, {58, 175, 217}}}, -{"minecraft:light_blue_concrete", {BLOCK_OPAQUE, {35, 137, 198}}}, -{"minecraft:light_blue_concrete_powder", {BLOCK_OPAQUE, {74, 180, 213}}}, -{"minecraft:light_blue_glazed_terracotta", {BLOCK_OPAQUE, {94, 164, 208}}}, -{"minecraft:light_blue_shulker_box", {BLOCK_OPAQUE, {49, 163, 212}}}, -{"minecraft:light_blue_stained_glass", {BLOCK_OPAQUE, {102, 153, 216}}}, -{"minecraft:light_blue_stained_glass_pane", {BLOCK_OPAQUE, {97, 147, 208}}}, -{"minecraft:light_blue_terracotta", {BLOCK_OPAQUE, {113, 108, 137}}}, -{"minecraft:light_blue_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:light_blue_wool", {BLOCK_OPAQUE, {58, 175, 217}}}, -{"minecraft:light_gray_banner", {0, {0, 0, 0}}}, -{"minecraft:light_gray_bed", {0, {0, 0, 0}}}, -{"minecraft:light_gray_candle", {0, {0, 0, 0}}}, -{"minecraft:light_gray_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:light_gray_carpet", {BLOCK_OPAQUE, {142, 142, 134}}}, -{"minecraft:light_gray_concrete", {BLOCK_OPAQUE, {125, 125, 115}}}, -{"minecraft:light_gray_concrete_powder", {BLOCK_OPAQUE, {154, 154, 148}}}, -{"minecraft:light_gray_glazed_terracotta", {BLOCK_OPAQUE, {144, 166, 167}}}, -{"minecraft:light_gray_shulker_box", {BLOCK_OPAQUE, {124, 124, 115}}}, -{"minecraft:light_gray_stained_glass", {BLOCK_OPAQUE, {153, 153, 153}}}, -{"minecraft:light_gray_stained_glass_pane", {BLOCK_OPAQUE, {147, 147, 147}}}, -{"minecraft:light_gray_terracotta", {BLOCK_OPAQUE, {135, 106, 97}}}, -{"minecraft:light_gray_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:light_gray_wool", {BLOCK_OPAQUE, {142, 142, 134}}}, -{"minecraft:light_weighted_pressure_plate", {BLOCK_OPAQUE, {246, 208, 61}}}, -{"minecraft:lightning_rod", {0, {0, 0, 0}}}, -{"minecraft:lilac", {BLOCK_OPAQUE, {154, 125, 147}}}, -{"minecraft:lily_of_the_valley", {0, {0, 0, 0}}}, -{"minecraft:lily_pad", {BLOCK_OPAQUE|BLOCK_GRASS, {133, 133, 133}}}, -{"minecraft:lime_banner", {0, {0, 0, 0}}}, -{"minecraft:lime_bed", {0, {0, 0, 0}}}, -{"minecraft:lime_candle", {0, {0, 0, 0}}}, -{"minecraft:lime_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:lime_carpet", {BLOCK_OPAQUE, {112, 185, 25}}}, -{"minecraft:lime_concrete", {BLOCK_OPAQUE, {94, 168, 24}}}, -{"minecraft:lime_concrete_powder", {BLOCK_OPAQUE, {125, 189, 41}}}, -{"minecraft:lime_glazed_terracotta", {BLOCK_OPAQUE, {162, 197, 55}}}, -{"minecraft:lime_shulker_box", {BLOCK_OPAQUE, {99, 172, 23}}}, -{"minecraft:lime_stained_glass", {BLOCK_OPAQUE, {127, 204, 25}}}, -{"minecraft:lime_stained_glass_pane", {BLOCK_OPAQUE, {122, 196, 24}}}, -{"minecraft:lime_terracotta", {BLOCK_OPAQUE, {103, 117, 52}}}, -{"minecraft:lime_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:lime_wool", {BLOCK_OPAQUE, {112, 185, 25}}}, -{"minecraft:lodestone", {BLOCK_OPAQUE, {147, 149, 152}}}, -{"minecraft:loom", {BLOCK_OPAQUE, {142, 119, 91}}}, -{"minecraft:magenta_banner", {0, {0, 0, 0}}}, -{"minecraft:magenta_bed", {0, {0, 0, 0}}}, -{"minecraft:magenta_candle", {0, {0, 0, 0}}}, -{"minecraft:magenta_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:magenta_carpet", {BLOCK_OPAQUE, {189, 68, 179}}}, -{"minecraft:magenta_concrete", {BLOCK_OPAQUE, {169, 48, 159}}}, -{"minecraft:magenta_concrete_powder", {BLOCK_OPAQUE, {192, 83, 184}}}, -{"minecraft:magenta_glazed_terracotta", {BLOCK_OPAQUE, {208, 100, 191}}}, -{"minecraft:magenta_shulker_box", {BLOCK_OPAQUE, {173, 54, 163}}}, -{"minecraft:magenta_stained_glass", {BLOCK_OPAQUE, {178, 76, 216}}}, -{"minecraft:magenta_stained_glass_pane", {BLOCK_OPAQUE, {171, 73, 208}}}, -{"minecraft:magenta_terracotta", {BLOCK_OPAQUE, {149, 88, 108}}}, -{"minecraft:magenta_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:magenta_wool", {BLOCK_OPAQUE, {189, 68, 179}}}, -{"minecraft:magma_block", {BLOCK_OPAQUE, {142, 63, 31}}}, -{"minecraft:mangrove_button", {0, {0, 0, 0}}}, -{"minecraft:mangrove_door", {BLOCK_OPAQUE, {112, 48, 46}}}, -{"minecraft:mangrove_fence", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_fence_gate", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {129, 128, 128}}}, -{"minecraft:mangrove_log", {BLOCK_OPAQUE, {102, 48, 42}}}, -{"minecraft:mangrove_planks", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_pressure_plate", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}}, -{"minecraft:mangrove_roots", {BLOCK_OPAQUE, {74, 59, 38}}}, -{"minecraft:mangrove_sign", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_slab", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_stairs", {BLOCK_OPAQUE, {117, 54, 48}}}, -{"minecraft:mangrove_trapdoor", {BLOCK_OPAQUE, {110, 46, 42}}}, -{"minecraft:mangrove_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:mangrove_wood", {BLOCK_OPAQUE, {83, 66, 41}}}, -{"minecraft:medium_amethyst_bud", {0, {0, 0, 0}}}, -{"minecraft:melon", {BLOCK_OPAQUE, {111, 144, 30}}}, -{"minecraft:melon_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {153, 153, 153}}}, -{"minecraft:moss_block", {BLOCK_OPAQUE, {89, 109, 45}}}, -{"minecraft:moss_carpet", {BLOCK_OPAQUE, {89, 109, 45}}}, -{"minecraft:mossy_cobblestone", {BLOCK_OPAQUE, {110, 118, 94}}}, -{"minecraft:mossy_cobblestone_slab", {BLOCK_OPAQUE, {110, 118, 94}}}, -{"minecraft:mossy_cobblestone_stairs", {BLOCK_OPAQUE, {110, 118, 94}}}, -{"minecraft:mossy_cobblestone_wall", {BLOCK_OPAQUE, {110, 118, 94}}}, -{"minecraft:mossy_stone_brick_slab", {BLOCK_OPAQUE, {115, 121, 105}}}, -{"minecraft:mossy_stone_brick_stairs", {BLOCK_OPAQUE, {115, 121, 105}}}, -{"minecraft:mossy_stone_brick_wall", {BLOCK_OPAQUE, {115, 121, 105}}}, -{"minecraft:mossy_stone_bricks", {BLOCK_OPAQUE, {115, 121, 105}}}, -{"minecraft:moving_piston", {0, {0, 0, 0}}}, -{"minecraft:mud", {BLOCK_OPAQUE, {60, 57, 60}}}, -{"minecraft:mud_brick_slab", {BLOCK_OPAQUE, {137, 103, 79}}}, -{"minecraft:mud_brick_stairs", {BLOCK_OPAQUE, {137, 103, 79}}}, -{"minecraft:mud_brick_wall", {BLOCK_OPAQUE, {137, 103, 79}}}, -{"minecraft:mud_bricks", {BLOCK_OPAQUE, {137, 103, 79}}}, -{"minecraft:muddy_mangrove_roots", {BLOCK_OPAQUE, {70, 58, 45}}}, -{"minecraft:mushroom_stem", {BLOCK_OPAQUE, {203, 196, 185}}}, -{"minecraft:mycelium", {BLOCK_OPAQUE, {111, 98, 101}}}, -{"minecraft:nether_brick_fence", {BLOCK_OPAQUE, {44, 21, 26}}}, -{"minecraft:nether_brick_slab", {BLOCK_OPAQUE, {44, 21, 26}}}, -{"minecraft:nether_brick_stairs", {BLOCK_OPAQUE, {44, 21, 26}}}, -{"minecraft:nether_brick_wall", {BLOCK_OPAQUE, {44, 21, 26}}}, -{"minecraft:nether_bricks", {BLOCK_OPAQUE, {44, 21, 26}}}, -{"minecraft:nether_gold_ore", {BLOCK_OPAQUE, {115, 54, 42}}}, -{"minecraft:nether_portal", {BLOCK_OPAQUE, {89, 11, 192}}}, -{"minecraft:nether_quartz_ore", {BLOCK_OPAQUE, {117, 65, 62}}}, -{"minecraft:nether_sprouts", {BLOCK_OPAQUE, {19, 151, 133}}}, -{"minecraft:nether_wart", {BLOCK_OPAQUE, {111, 18, 19}}}, -{"minecraft:nether_wart_block", {BLOCK_OPAQUE, {114, 2, 2}}}, -{"minecraft:netherite_block", {BLOCK_OPAQUE, {66, 61, 63}}}, -{"minecraft:netherrack", {BLOCK_OPAQUE, {97, 38, 38}}}, -{"minecraft:note_block", {BLOCK_OPAQUE, {88, 58, 40}}}, -{"minecraft:oak_button", {0, {0, 0, 0}}}, -{"minecraft:oak_door", {BLOCK_OPAQUE, {140, 110, 66}}}, -{"minecraft:oak_fence", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_fence_gate", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_leaves", {BLOCK_OPAQUE|BLOCK_FOLIAGE, {144, 144, 144}}}, -{"minecraft:oak_log", {BLOCK_OPAQUE, {151, 121, 73}}}, -{"minecraft:oak_planks", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_pressure_plate", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}}, -{"minecraft:oak_sign", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_stairs", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:oak_trapdoor", {BLOCK_OPAQUE, {124, 99, 56}}}, -{"minecraft:oak_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:oak_wood", {BLOCK_OPAQUE, {109, 85, 50}}}, -{"minecraft:observer", {BLOCK_OPAQUE, {98, 98, 98}}}, -{"minecraft:obsidian", {BLOCK_OPAQUE, {15, 10, 24}}}, -{"minecraft:ochre_froglight", {BLOCK_OPAQUE, {250, 245, 206}}}, -{"minecraft:orange_banner", {0, {0, 0, 0}}}, -{"minecraft:orange_bed", {0, {0, 0, 0}}}, -{"minecraft:orange_candle", {0, {0, 0, 0}}}, -{"minecraft:orange_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:orange_carpet", {BLOCK_OPAQUE, {240, 118, 19}}}, -{"minecraft:orange_concrete", {BLOCK_OPAQUE, {224, 97, 0}}}, -{"minecraft:orange_concrete_powder", {BLOCK_OPAQUE, {227, 131, 31}}}, -{"minecraft:orange_glazed_terracotta", {BLOCK_OPAQUE, {154, 147, 91}}}, -{"minecraft:orange_shulker_box", {BLOCK_OPAQUE, {234, 106, 8}}}, -{"minecraft:orange_stained_glass", {BLOCK_OPAQUE, {216, 127, 51}}}, -{"minecraft:orange_stained_glass_pane", {BLOCK_OPAQUE, {208, 122, 48}}}, -{"minecraft:orange_terracotta", {BLOCK_OPAQUE, {161, 83, 37}}}, -{"minecraft:orange_tulip", {0, {0, 0, 0}}}, -{"minecraft:orange_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:orange_wool", {BLOCK_OPAQUE, {240, 118, 19}}}, -{"minecraft:oxeye_daisy", {0, {0, 0, 0}}}, -{"minecraft:oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}}, -{"minecraft:oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:packed_ice", {BLOCK_OPAQUE, {141, 180, 250}}}, -{"minecraft:packed_mud", {BLOCK_OPAQUE, {142, 106, 79}}}, -{"minecraft:pearlescent_froglight", {BLOCK_OPAQUE, {245, 240, 239}}}, -{"minecraft:peony", {BLOCK_OPAQUE, {129, 126, 139}}}, -{"minecraft:petrified_oak_slab", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:pink_banner", {0, {0, 0, 0}}}, -{"minecraft:pink_bed", {0, {0, 0, 0}}}, -{"minecraft:pink_candle", {0, {0, 0, 0}}}, -{"minecraft:pink_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:pink_carpet", {BLOCK_OPAQUE, {237, 141, 172}}}, -{"minecraft:pink_concrete", {BLOCK_OPAQUE, {213, 101, 142}}}, -{"minecraft:pink_concrete_powder", {BLOCK_OPAQUE, {228, 153, 181}}}, -{"minecraft:pink_glazed_terracotta", {BLOCK_OPAQUE, {235, 154, 181}}}, -{"minecraft:pink_shulker_box", {BLOCK_OPAQUE, {230, 121, 157}}}, -{"minecraft:pink_stained_glass", {BLOCK_OPAQUE, {242, 127, 165}}}, -{"minecraft:pink_stained_glass_pane", {BLOCK_OPAQUE, {233, 122, 159}}}, -{"minecraft:pink_terracotta", {BLOCK_OPAQUE, {161, 78, 78}}}, -{"minecraft:pink_tulip", {0, {0, 0, 0}}}, -{"minecraft:pink_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:pink_wool", {BLOCK_OPAQUE, {237, 141, 172}}}, -{"minecraft:piston", {BLOCK_OPAQUE, {109, 104, 96}}}, -{"minecraft:piston_head", {BLOCK_OPAQUE, {153, 127, 85}}}, -{"minecraft:player_head", {0, {0, 0, 0}}}, -{"minecraft:player_wall_head", {0, {0, 0, 0}}}, -{"minecraft:podzol", {BLOCK_OPAQUE, {91, 63, 24}}}, -{"minecraft:pointed_dripstone", {BLOCK_OPAQUE, {129, 102, 89}}}, -{"minecraft:polished_andesite", {BLOCK_OPAQUE, {132, 134, 133}}}, -{"minecraft:polished_andesite_slab", {BLOCK_OPAQUE, {132, 134, 133}}}, -{"minecraft:polished_andesite_stairs", {BLOCK_OPAQUE, {132, 134, 133}}}, -{"minecraft:polished_basalt", {BLOCK_OPAQUE, {99, 98, 100}}}, -{"minecraft:polished_blackstone", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_blackstone_brick_slab", {BLOCK_OPAQUE, {48, 42, 49}}}, -{"minecraft:polished_blackstone_brick_stairs", {BLOCK_OPAQUE, {48, 42, 49}}}, -{"minecraft:polished_blackstone_brick_wall", {BLOCK_OPAQUE, {48, 42, 49}}}, -{"minecraft:polished_blackstone_bricks", {BLOCK_OPAQUE, {48, 42, 49}}}, -{"minecraft:polished_blackstone_button", {0, {0, 0, 0}}}, -{"minecraft:polished_blackstone_pressure_plate", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_blackstone_slab", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_blackstone_stairs", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_blackstone_wall", {BLOCK_OPAQUE, {53, 48, 56}}}, -{"minecraft:polished_deepslate", {BLOCK_OPAQUE, {72, 72, 73}}}, -{"minecraft:polished_deepslate_slab", {BLOCK_OPAQUE, {72, 72, 73}}}, -{"minecraft:polished_deepslate_stairs", {BLOCK_OPAQUE, {72, 72, 73}}}, -{"minecraft:polished_deepslate_wall", {BLOCK_OPAQUE, {72, 72, 73}}}, -{"minecraft:polished_diorite", {BLOCK_OPAQUE, {192, 193, 194}}}, -{"minecraft:polished_diorite_slab", {BLOCK_OPAQUE, {192, 193, 194}}}, -{"minecraft:polished_diorite_stairs", {BLOCK_OPAQUE, {192, 193, 194}}}, -{"minecraft:polished_granite", {BLOCK_OPAQUE, {154, 106, 89}}}, -{"minecraft:polished_granite_slab", {BLOCK_OPAQUE, {154, 106, 89}}}, -{"minecraft:polished_granite_stairs", {BLOCK_OPAQUE, {154, 106, 89}}}, -{"minecraft:poppy", {0, {0, 0, 0}}}, -{"minecraft:potatoes", {BLOCK_OPAQUE, {84, 135, 47}}}, -{"minecraft:potted_acacia_sapling", {BLOCK_OPAQUE, {118, 117, 23}}}, -{"minecraft:potted_allium", {BLOCK_OPAQUE, {158, 137, 183}}}, -{"minecraft:potted_azalea_bush", {BLOCK_OPAQUE, {101, 124, 47}}}, -{"minecraft:potted_azure_bluet", {BLOCK_OPAQUE, {169, 204, 127}}}, -{"minecraft:potted_bamboo", {BLOCK_OPAQUE, {93, 144, 19}}}, -{"minecraft:potted_birch_sapling", {BLOCK_OPAQUE, {127, 160, 79}}}, -{"minecraft:potted_blue_orchid", {BLOCK_OPAQUE, {47, 162, 168}}}, -{"minecraft:potted_brown_mushroom", {BLOCK_OPAQUE, {153, 116, 92}}}, -{"minecraft:potted_cactus", {BLOCK_OPAQUE, {85, 127, 43}}}, -{"minecraft:potted_cornflower", {BLOCK_OPAQUE, {79, 121, 146}}}, -{"minecraft:potted_crimson_fungus", {BLOCK_OPAQUE, {141, 44, 29}}}, -{"minecraft:potted_crimson_roots", {BLOCK_OPAQUE, {127, 8, 41}}}, -{"minecraft:potted_dandelion", {BLOCK_OPAQUE, {147, 172, 43}}}, -{"minecraft:potted_dark_oak_sapling", {BLOCK_OPAQUE, {61, 90, 30}}}, -{"minecraft:potted_dead_bush", {BLOCK_OPAQUE, {107, 78, 40}}}, -{"minecraft:potted_fern", {BLOCK_OPAQUE|BLOCK_GRASS, {124, 124, 124}}}, -{"minecraft:potted_flowering_azalea_bush", {BLOCK_OPAQUE, {112, 121, 64}}}, -{"minecraft:potted_jungle_sapling", {BLOCK_OPAQUE, {47, 81, 16}}}, -{"minecraft:potted_lily_of_the_valley", {BLOCK_OPAQUE, {123, 174, 95}}}, -{"minecraft:potted_mangrove_propagule", {BLOCK_OPAQUE, {96, 174, 83}}}, -{"minecraft:potted_oak_sapling", {BLOCK_OPAQUE, {77, 106, 40}}}, -{"minecraft:potted_orange_tulip", {BLOCK_OPAQUE, {93, 142, 30}}}, -{"minecraft:potted_oxeye_daisy", {BLOCK_OPAQUE, {179, 202, 143}}}, -{"minecraft:potted_pink_tulip", {BLOCK_OPAQUE, {99, 157, 78}}}, -{"minecraft:potted_poppy", {BLOCK_OPAQUE, {128, 64, 37}}}, -{"minecraft:potted_red_mushroom", {BLOCK_OPAQUE, {216, 75, 67}}}, -{"minecraft:potted_red_tulip", {BLOCK_OPAQUE, {89, 128, 32}}}, -{"minecraft:potted_spruce_sapling", {BLOCK_OPAQUE, {44, 60, 36}}}, -{"minecraft:potted_warped_fungus", {BLOCK_OPAQUE, {74, 109, 87}}}, -{"minecraft:potted_warped_roots", {BLOCK_OPAQUE, {20, 136, 123}}}, -{"minecraft:potted_white_tulip", {BLOCK_OPAQUE, {93, 164, 71}}}, -{"minecraft:potted_wither_rose", {BLOCK_OPAQUE, {41, 44, 23}}}, -{"minecraft:powder_snow", {BLOCK_OPAQUE, {248, 253, 253}}}, -{"minecraft:powder_snow_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, -{"minecraft:powered_rail", {BLOCK_OPAQUE, {137, 109, 74}}}, -{"minecraft:prismarine", {BLOCK_OPAQUE, {99, 156, 151}}}, -{"minecraft:prismarine_brick_slab", {BLOCK_OPAQUE, {99, 171, 158}}}, -{"minecraft:prismarine_brick_stairs", {BLOCK_OPAQUE, {99, 171, 158}}}, -{"minecraft:prismarine_bricks", {BLOCK_OPAQUE, {99, 171, 158}}}, -{"minecraft:prismarine_slab", {BLOCK_OPAQUE, {99, 156, 151}}}, -{"minecraft:prismarine_stairs", {BLOCK_OPAQUE, {99, 156, 151}}}, -{"minecraft:prismarine_wall", {BLOCK_OPAQUE, {99, 156, 151}}}, -{"minecraft:pumpkin", {BLOCK_OPAQUE, {198, 118, 24}}}, -{"minecraft:pumpkin_stem", {BLOCK_OPAQUE|BLOCK_GRASS, {154, 154, 154}}}, -{"minecraft:purple_banner", {0, {0, 0, 0}}}, -{"minecraft:purple_bed", {0, {0, 0, 0}}}, -{"minecraft:purple_candle", {0, {0, 0, 0}}}, -{"minecraft:purple_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:purple_carpet", {BLOCK_OPAQUE, {121, 42, 172}}}, -{"minecraft:purple_concrete", {BLOCK_OPAQUE, {100, 31, 156}}}, -{"minecraft:purple_concrete_powder", {BLOCK_OPAQUE, {131, 55, 177}}}, -{"minecraft:purple_glazed_terracotta", {BLOCK_OPAQUE, {109, 48, 152}}}, -{"minecraft:purple_shulker_box", {BLOCK_OPAQUE, {103, 32, 156}}}, -{"minecraft:purple_stained_glass", {BLOCK_OPAQUE, {127, 63, 178}}}, -{"minecraft:purple_stained_glass_pane", {BLOCK_OPAQUE, {122, 61, 171}}}, -{"minecraft:purple_terracotta", {BLOCK_OPAQUE, {118, 70, 86}}}, -{"minecraft:purple_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:purple_wool", {BLOCK_OPAQUE, {121, 42, 172}}}, -{"minecraft:purpur_block", {BLOCK_OPAQUE, {169, 125, 169}}}, -{"minecraft:purpur_pillar", {BLOCK_OPAQUE, {171, 129, 171}}}, -{"minecraft:purpur_slab", {BLOCK_OPAQUE, {169, 125, 169}}}, -{"minecraft:purpur_stairs", {BLOCK_OPAQUE, {169, 125, 169}}}, -{"minecraft:quartz_block", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:quartz_bricks", {BLOCK_OPAQUE, {234, 229, 221}}}, -{"minecraft:quartz_pillar", {BLOCK_OPAQUE, {235, 230, 224}}}, -{"minecraft:quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:rail", {BLOCK_OPAQUE, {125, 111, 88}}}, -{"minecraft:raw_copper_block", {BLOCK_OPAQUE, {154, 105, 79}}}, -{"minecraft:raw_gold_block", {BLOCK_OPAQUE, {221, 169, 46}}}, -{"minecraft:raw_iron_block", {BLOCK_OPAQUE, {166, 135, 107}}}, -{"minecraft:red_banner", {0, {0, 0, 0}}}, -{"minecraft:red_bed", {0, {0, 0, 0}}}, -{"minecraft:red_candle", {0, {0, 0, 0}}}, -{"minecraft:red_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:red_carpet", {BLOCK_OPAQUE, {160, 39, 34}}}, -{"minecraft:red_concrete", {BLOCK_OPAQUE, {142, 32, 32}}}, -{"minecraft:red_concrete_powder", {BLOCK_OPAQUE, {168, 54, 50}}}, -{"minecraft:red_glazed_terracotta", {BLOCK_OPAQUE, {181, 59, 53}}}, -{"minecraft:red_mushroom", {0, {0, 0, 0}}}, -{"minecraft:red_mushroom_block", {BLOCK_OPAQUE, {200, 46, 45}}}, -{"minecraft:red_nether_brick_slab", {BLOCK_OPAQUE, {69, 7, 9}}}, -{"minecraft:red_nether_brick_stairs", {BLOCK_OPAQUE, {69, 7, 9}}}, -{"minecraft:red_nether_brick_wall", {BLOCK_OPAQUE, {69, 7, 9}}}, -{"minecraft:red_nether_bricks", {BLOCK_OPAQUE, {69, 7, 9}}}, -{"minecraft:red_sand", {BLOCK_OPAQUE, {190, 102, 33}}}, -{"minecraft:red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:red_sandstone_stairs", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:red_sandstone_wall", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:red_shulker_box", {BLOCK_OPAQUE, {140, 31, 30}}}, -{"minecraft:red_stained_glass", {BLOCK_OPAQUE, {153, 51, 51}}}, -{"minecraft:red_stained_glass_pane", {BLOCK_OPAQUE, {147, 48, 48}}}, -{"minecraft:red_terracotta", {BLOCK_OPAQUE, {143, 61, 46}}}, -{"minecraft:red_tulip", {0, {0, 0, 0}}}, -{"minecraft:red_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:red_wool", {BLOCK_OPAQUE, {160, 39, 34}}}, -{"minecraft:redstone_block", {BLOCK_OPAQUE, {175, 24, 5}}}, -{"minecraft:redstone_lamp", {BLOCK_OPAQUE, {95, 54, 30}}}, -{"minecraft:redstone_ore", {BLOCK_OPAQUE, {140, 109, 109}}}, -{"minecraft:redstone_torch", {0, {0, 0, 0}}}, -{"minecraft:redstone_wall_torch", {0, {0, 0, 0}}}, -{"minecraft:redstone_wire", {BLOCK_OPAQUE, {175, 24, 5}}}, -{"minecraft:reinforced_deepslate", {BLOCK_OPAQUE, {80, 82, 78}}}, -{"minecraft:repeater", {BLOCK_OPAQUE, {160, 157, 156}}}, -{"minecraft:repeating_command_block", {BLOCK_OPAQUE, {129, 111, 176}}}, -{"minecraft:respawn_anchor", {BLOCK_OPAQUE, {75, 26, 144}}}, -{"minecraft:rooted_dirt", {BLOCK_OPAQUE, {144, 103, 76}}}, -{"minecraft:rose_bush", {BLOCK_OPAQUE, {131, 66, 37}}}, -{"minecraft:sand", {BLOCK_OPAQUE, {219, 207, 163}}}, -{"minecraft:sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:sandstone_wall", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:scaffolding", {BLOCK_OPAQUE, {174, 134, 80}}}, -{"minecraft:sculk", {BLOCK_OPAQUE, {12, 29, 36}}}, -{"minecraft:sculk_catalyst", {BLOCK_OPAQUE, {15, 31, 38}}}, -{"minecraft:sculk_sensor", {BLOCK_OPAQUE, {7, 70, 84}}}, -{"minecraft:sculk_shrieker", {BLOCK_OPAQUE, {198, 205, 169}}}, -{"minecraft:sculk_vein", {BLOCK_OPAQUE, {7, 48, 57}}}, -{"minecraft:sea_lantern", {BLOCK_OPAQUE, {172, 199, 190}}}, -{"minecraft:sea_pickle", {BLOCK_OPAQUE, {90, 97, 39}}}, -{"minecraft:seagrass", {0, {0, 0, 0}}}, -{"minecraft:shroomlight", {BLOCK_OPAQUE, {240, 146, 70}}}, -{"minecraft:shulker_box", {BLOCK_OPAQUE, {139, 96, 139}}}, -{"minecraft:sign", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:skeleton_skull", {0, {0, 0, 0}}}, -{"minecraft:skeleton_wall_skull", {0, {0, 0, 0}}}, -{"minecraft:slime_block", {BLOCK_OPAQUE, {111, 192, 91}}}, -{"minecraft:small_amethyst_bud", {0, {0, 0, 0}}}, -{"minecraft:small_dripleaf", {0, {0, 0, 0}}}, -{"minecraft:smithing_table", {BLOCK_OPAQUE, {57, 58, 70}}}, -{"minecraft:smoker", {BLOCK_OPAQUE, {85, 83, 81}}}, -{"minecraft:smooth_basalt", {BLOCK_OPAQUE, {72, 72, 78}}}, -{"minecraft:smooth_quartz", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:smooth_quartz_slab", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:smooth_quartz_stairs", {BLOCK_OPAQUE, {235, 229, 222}}}, -{"minecraft:smooth_red_sandstone", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:smooth_red_sandstone_slab", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:smooth_red_sandstone_stairs", {BLOCK_OPAQUE, {181, 97, 31}}}, -{"minecraft:smooth_sandstone", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:smooth_sandstone_slab", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:smooth_sandstone_stairs", {BLOCK_OPAQUE, {223, 214, 170}}}, -{"minecraft:smooth_stone", {BLOCK_OPAQUE, {158, 158, 158}}}, -{"minecraft:smooth_stone_slab", {BLOCK_OPAQUE, {158, 158, 158}}}, -{"minecraft:snow", {BLOCK_OPAQUE, {249, 254, 254}}}, -{"minecraft:snow_block", {BLOCK_OPAQUE, {249, 254, 254}}}, -{"minecraft:soul_campfire", {BLOCK_OPAQUE, {80, 204, 208}}}, -{"minecraft:soul_fire", {BLOCK_OPAQUE, {51, 192, 197}}}, -{"minecraft:soul_lantern", {BLOCK_OPAQUE, {71, 99, 114}}}, -{"minecraft:soul_sand", {BLOCK_OPAQUE, {81, 62, 50}}}, -{"minecraft:soul_soil", {BLOCK_OPAQUE, {75, 57, 46}}}, -{"minecraft:soul_torch", {0, {0, 0, 0}}}, -{"minecraft:soul_wall_torch", {0, {0, 0, 0}}}, -{"minecraft:spawner", {BLOCK_OPAQUE, {36, 46, 62}}}, -{"minecraft:sponge", {BLOCK_OPAQUE, {195, 192, 74}}}, -{"minecraft:spore_blossom", {BLOCK_OPAQUE, {206, 96, 158}}}, -{"minecraft:spruce_button", {0, {0, 0, 0}}}, -{"minecraft:spruce_door", {BLOCK_OPAQUE, {106, 80, 48}}}, -{"minecraft:spruce_fence", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_fence_gate", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_leaves", {BLOCK_OPAQUE|BLOCK_SPRUCE, {126, 126, 126}}}, -{"minecraft:spruce_log", {BLOCK_OPAQUE, {108, 80, 46}}}, -{"minecraft:spruce_planks", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_pressure_plate", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_sapling", {BLOCK_OPAQUE, {44, 60, 36}}}, -{"minecraft:spruce_sign", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_slab", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_stairs", {BLOCK_OPAQUE, {114, 84, 48}}}, -{"minecraft:spruce_trapdoor", {BLOCK_OPAQUE, {103, 79, 47}}}, -{"minecraft:spruce_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:spruce_wood", {BLOCK_OPAQUE, {58, 37, 16}}}, -{"minecraft:sticky_piston", {BLOCK_OPAQUE, {109, 104, 96}}}, -{"minecraft:stone", {BLOCK_OPAQUE, {125, 125, 125}}}, -{"minecraft:stone_brick_slab", {BLOCK_OPAQUE, {122, 121, 122}}}, -{"minecraft:stone_brick_stairs", {BLOCK_OPAQUE, {122, 121, 122}}}, -{"minecraft:stone_brick_wall", {BLOCK_OPAQUE, {122, 121, 122}}}, -{"minecraft:stone_bricks", {BLOCK_OPAQUE, {122, 121, 122}}}, -{"minecraft:stone_button", {0, {0, 0, 0}}}, -{"minecraft:stone_pressure_plate", {BLOCK_OPAQUE, {125, 125, 125}}}, -{"minecraft:stone_slab", {BLOCK_OPAQUE, {125, 125, 125}}}, -{"minecraft:stone_stairs", {BLOCK_OPAQUE, {125, 125, 125}}}, -{"minecraft:stonecutter", {BLOCK_OPAQUE, {123, 118, 111}}}, -{"minecraft:stripped_acacia_log", {BLOCK_OPAQUE, {166, 91, 51}}}, -{"minecraft:stripped_acacia_wood", {BLOCK_OPAQUE, {174, 92, 59}}}, -{"minecraft:stripped_birch_log", {BLOCK_OPAQUE, {191, 171, 116}}}, -{"minecraft:stripped_birch_wood", {BLOCK_OPAQUE, {196, 176, 118}}}, -{"minecraft:stripped_crimson_hyphae", {BLOCK_OPAQUE, {137, 57, 90}}}, -{"minecraft:stripped_crimson_stem", {BLOCK_OPAQUE, {121, 56, 82}}}, -{"minecraft:stripped_dark_oak_log", {BLOCK_OPAQUE, {65, 44, 22}}}, -{"minecraft:stripped_dark_oak_wood", {BLOCK_OPAQUE, {72, 56, 36}}}, -{"minecraft:stripped_jungle_log", {BLOCK_OPAQUE, {165, 122, 81}}}, -{"minecraft:stripped_jungle_wood", {BLOCK_OPAQUE, {171, 132, 84}}}, -{"minecraft:stripped_mangrove_log", {BLOCK_OPAQUE, {109, 43, 43}}}, -{"minecraft:stripped_mangrove_wood", {BLOCK_OPAQUE, {119, 54, 47}}}, -{"minecraft:stripped_oak_log", {BLOCK_OPAQUE, {160, 129, 77}}}, -{"minecraft:stripped_oak_wood", {BLOCK_OPAQUE, {177, 144, 86}}}, -{"minecraft:stripped_spruce_log", {BLOCK_OPAQUE, {105, 80, 46}}}, -{"minecraft:stripped_spruce_wood", {BLOCK_OPAQUE, {115, 89, 52}}}, -{"minecraft:stripped_warped_hyphae", {BLOCK_OPAQUE, {57, 150, 147}}}, -{"minecraft:stripped_warped_stem", {BLOCK_OPAQUE, {52, 128, 124}}}, -{"minecraft:structure_block", {BLOCK_OPAQUE, {88, 74, 90}}}, -{"minecraft:structure_void", {0, {0, 0, 0}}}, -{"minecraft:sugar_cane", {BLOCK_OPAQUE, {148, 192, 101}}}, -{"minecraft:sunflower", {BLOCK_OPAQUE, {246, 196, 54}}}, -{"minecraft:sweet_berry_bush", {BLOCK_OPAQUE, {68, 77, 50}}}, -{"minecraft:tall_grass", {BLOCK_OPAQUE|BLOCK_GRASS, {151, 149, 151}}}, -{"minecraft:tall_seagrass", {BLOCK_OPAQUE, {59, 139, 14}}}, -{"minecraft:target", {BLOCK_OPAQUE, {226, 170, 157}}}, -{"minecraft:terracotta", {BLOCK_OPAQUE, {152, 94, 67}}}, -{"minecraft:tinted_glass", {BLOCK_OPAQUE, {44, 38, 46}}}, -{"minecraft:tnt", {BLOCK_OPAQUE, {142, 62, 53}}}, -{"minecraft:torch", {0, {0, 0, 0}}}, -{"minecraft:trapped_chest", {BLOCK_OPAQUE, {162, 130, 78}}}, -{"minecraft:tripwire", {0, {0, 0, 0}}}, -{"minecraft:tripwire_hook", {0, {0, 0, 0}}}, -{"minecraft:tube_coral", {0, {0, 0, 0}}}, -{"minecraft:tube_coral_block", {BLOCK_OPAQUE, {49, 87, 206}}}, -{"minecraft:tube_coral_fan", {0, {0, 0, 0}}}, -{"minecraft:tube_coral_wall_fan", {0, {0, 0, 0}}}, -{"minecraft:tuff", {BLOCK_OPAQUE, {108, 109, 102}}}, -{"minecraft:turtle_egg", {BLOCK_OPAQUE, {228, 226, 191}}}, -{"minecraft:twisting_vines", {BLOCK_OPAQUE, {20, 143, 124}}}, -{"minecraft:twisting_vines_plant", {BLOCK_OPAQUE, {20, 135, 122}}}, -{"minecraft:verdant_froglight", {BLOCK_OPAQUE, {229, 244, 228}}}, -{"minecraft:vine", {BLOCK_OPAQUE|BLOCK_GRASS, {116, 116, 116}}}, -{"minecraft:void_air", {0, {0, 0, 0}}}, -{"minecraft:wall_sign", {0, {0, 0, 0}}}, -{"minecraft:wall_torch", {0, {0, 0, 0}}}, -{"minecraft:warped_button", {0, {0, 0, 0}}}, -{"minecraft:warped_door", {BLOCK_OPAQUE, {44, 126, 120}}}, -{"minecraft:warped_fence", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_fence_gate", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_fungus", {0, {0, 0, 0}}}, -{"minecraft:warped_hyphae", {BLOCK_OPAQUE, {58, 58, 77}}}, -{"minecraft:warped_nylium", {BLOCK_OPAQUE, {43, 114, 101}}}, -{"minecraft:warped_planks", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_pressure_plate", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_roots", {BLOCK_OPAQUE, {20, 138, 124}}}, -{"minecraft:warped_sign", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_slab", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_stairs", {BLOCK_OPAQUE, {43, 104, 99}}}, -{"minecraft:warped_stem", {BLOCK_OPAQUE, {53, 109, 110}}}, -{"minecraft:warped_trapdoor", {BLOCK_OPAQUE, {47, 119, 111}}}, -{"minecraft:warped_wall_sign", {0, {0, 0, 0}}}, -{"minecraft:warped_wart_block", {BLOCK_OPAQUE, {22, 119, 121}}}, -{"minecraft:water", {BLOCK_OPAQUE|BLOCK_WATER, {177, 177, 177}}}, -{"minecraft:water_cauldron", {BLOCK_OPAQUE, {73, 72, 74}}}, -{"minecraft:waxed_copper_block", {BLOCK_OPAQUE, {192, 107, 79}}}, -{"minecraft:waxed_cut_copper", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:waxed_cut_copper_slab", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:waxed_cut_copper_stairs", {BLOCK_OPAQUE, {191, 106, 80}}}, -{"minecraft:waxed_exposed_copper", {BLOCK_OPAQUE, {161, 125, 103}}}, -{"minecraft:waxed_exposed_cut_copper", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:waxed_exposed_cut_copper_slab", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:waxed_exposed_cut_copper_stairs", {BLOCK_OPAQUE, {154, 121, 101}}}, -{"minecraft:waxed_oxidized_copper", {BLOCK_OPAQUE, {82, 162, 132}}}, -{"minecraft:waxed_oxidized_cut_copper", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:waxed_oxidized_cut_copper_slab", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:waxed_oxidized_cut_copper_stairs", {BLOCK_OPAQUE, {79, 153, 126}}}, -{"minecraft:waxed_weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}}, -{"minecraft:waxed_weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:waxed_weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:waxed_weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:weathered_copper", {BLOCK_OPAQUE, {108, 153, 110}}}, -{"minecraft:weathered_cut_copper", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:weathered_cut_copper_slab", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:weathered_cut_copper_stairs", {BLOCK_OPAQUE, {109, 145, 107}}}, -{"minecraft:weeping_vines", {BLOCK_OPAQUE, {104, 1, 0}}}, -{"minecraft:weeping_vines_plant", {BLOCK_OPAQUE, {132, 16, 12}}}, -{"minecraft:wet_sponge", {BLOCK_OPAQUE, {171, 181, 70}}}, -{"minecraft:wheat", {BLOCK_OPAQUE, {166, 151, 73}}}, -{"minecraft:white_banner", {0, {0, 0, 0}}}, -{"minecraft:white_bed", {0, {0, 0, 0}}}, -{"minecraft:white_candle", {0, {0, 0, 0}}}, -{"minecraft:white_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:white_carpet", {BLOCK_OPAQUE, {233, 236, 236}}}, -{"minecraft:white_concrete", {BLOCK_OPAQUE, {207, 213, 214}}}, -{"minecraft:white_concrete_powder", {BLOCK_OPAQUE, {225, 227, 227}}}, -{"minecraft:white_glazed_terracotta", {BLOCK_OPAQUE, {188, 212, 202}}}, -{"minecraft:white_shulker_box", {BLOCK_OPAQUE, {215, 220, 221}}}, -{"minecraft:white_stained_glass", {BLOCK_OPAQUE, {255, 255, 255}}}, -{"minecraft:white_stained_glass_pane", {BLOCK_OPAQUE, {246, 246, 246}}}, -{"minecraft:white_terracotta", {BLOCK_OPAQUE, {209, 178, 161}}}, -{"minecraft:white_tulip", {0, {0, 0, 0}}}, -{"minecraft:white_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:white_wool", {BLOCK_OPAQUE, {233, 236, 236}}}, -{"minecraft:wither_rose", {0, {0, 0, 0}}}, -{"minecraft:wither_skeleton_skull", {0, {0, 0, 0}}}, -{"minecraft:wither_skeleton_wall_skull", {0, {0, 0, 0}}}, -{"minecraft:yellow_banner", {0, {0, 0, 0}}}, -{"minecraft:yellow_bed", {0, {0, 0, 0}}}, -{"minecraft:yellow_candle", {0, {0, 0, 0}}}, -{"minecraft:yellow_candle_cake", {BLOCK_OPAQUE, {248, 222, 214}}}, -{"minecraft:yellow_carpet", {BLOCK_OPAQUE, {248, 197, 39}}}, -{"minecraft:yellow_concrete", {BLOCK_OPAQUE, {240, 175, 21}}}, -{"minecraft:yellow_concrete_powder", {BLOCK_OPAQUE, {232, 199, 54}}}, -{"minecraft:yellow_glazed_terracotta", {BLOCK_OPAQUE, {234, 192, 88}}}, -{"minecraft:yellow_shulker_box", {BLOCK_OPAQUE, {248, 188, 29}}}, -{"minecraft:yellow_stained_glass", {BLOCK_OPAQUE, {229, 229, 51}}}, -{"minecraft:yellow_stained_glass_pane", {BLOCK_OPAQUE, {221, 221, 48}}}, -{"minecraft:yellow_terracotta", {BLOCK_OPAQUE, {186, 133, 35}}}, -{"minecraft:yellow_wall_banner", {0, {0, 0, 0}}}, -{"minecraft:yellow_wool", {BLOCK_OPAQUE, {248, 197, 39}}}, -{"minecraft:zombie_head", {0, {0, 0, 0}}}, -{"minecraft:zombie_wall_head", {0, {0, 0, 0}}}, diff --git a/src/Resource/Color.hpp b/src/Resource/Color.hpp deleted file mode 100644 index 255db1b..0000000 --- a/src/Resource/Color.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2018, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include - - -namespace MinedMap { -namespace Resource { - -struct FloatColor { - float r, g, b; -}; - -static inline FloatColor operator+(const FloatColor &a, const FloatColor &b){ - return FloatColor { - a.r+b.r, - a.g+b.g, - a.b+b.b, - }; -} - -static inline FloatColor & operator*=(FloatColor &a, const FloatColor &b) { - a.r *= b.r; - a.g *= b.g; - a.b *= b.b; - - return a; -} - -static inline FloatColor operator*(float s, const FloatColor &c) { - return FloatColor { - s*c.r, - s*c.g, - s*c.b, - }; -} - -struct Color { - uint8_t r, g, b, a; - - Color() : r(0), g(0), b(0), a(0) {} - Color(FloatColor c) : r(c.r), g(c.g), b(c.b), a(0xff) {} -}; - -} -} diff --git a/src/Resource/LegacyBlockType.inc.cpp b/src/Resource/LegacyBlockType.inc.cpp deleted file mode 100644 index b1dcdff..0000000 --- a/src/Resource/LegacyBlockType.inc.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* 0 */ simple("air"), -/* 1 */ { - "stone", - "granite", - "polished_granite", - "diorite", - "polished_diorite", - "andesite", - "polished_andesite", -}, -/* 2 */ simple("grass_block"), -/* 3 */ { - "dirt", - "coarse_dirt", - "podzol", -}, -/* 4 */ simple("cobblestone"), -/* 5 */ { - "oak_planks", - "spruce_planks", - "birch_planks", - "jungle_planks", - "acacia_planks", - "dark_oak_planks", -}, -/* 6 */ { - "oak_sapling", - "spruce_sapling", - "birch_sapling", - "jungle_sapling", - "acacia_sapling", - "dark_oak_sapling", - nullptr, - nullptr, - "oak_sapling", - "spruce_sapling", - "birch_sapling", - "jungle_sapling", - "acacia_sapling", - "dark_oak_sapling", -}, -/* 7 */ simple("bedrock"), -/* 8 */ simple("water"), -/* 9 */ simple("water"), -/* 10 */ simple("lava"), -/* 11 */ simple("lava"), -/* 12 */ { - "sand", - "red_sand", -}, -/* 13 */ simple("gravel"), -/* 14 */ simple("gold_ore"), -/* 15 */ simple("iron_ore"), -/* 16 */ simple("coal_ore"), -/* 17 */ { - "oak_log", - "spruce_log", - "birch_log", - "jungle_log", - "oak_log", - "spruce_log", - "birch_log", - "jungle_log", - "oak_log", - "spruce_log", - "birch_log", - "jungle_log", - "oak_log", - "spruce_log", - "birch_log", - "jungle_log", -}, -/* 18 */ { - "oak_leaves", - "spruce_leaves", - "birch_leaves", - "jungle_leaves", - "oak_leaves", - "spruce_leaves", - "birch_leaves", - "jungle_leaves", - "oak_leaves", - "spruce_leaves", - "birch_leaves", - "jungle_leaves", - "oak_leaves", - "spruce_leaves", - "birch_leaves", - "jungle_leaves", -}, -/* 19 */ simple("sponge"), -/* 20 */ simple("glass"), -/* 21 */ simple("lapis_ore"), -/* 22 */ simple("lapis_block"), -/* 23 */ simple("dispenser"), -/* 24 */ simple("sandstone"), -/* 25 */ simple("note_block"), -/* 26 */ {/* bed */}, -/* 27 */ simple("powered_rail"), -/* 28 */ simple("detector_rail"), -/* 29 */ simple("sticky_piston"), -/* 30 */ simple("cobweb"), -/* 31 */ { - "grass", - "fern", -}, -/* 32 */ simple("dead_bush"), -/* 33 */ simple("piston"), -/* 34 */ simple("piston_head"), -/* 35 */ { - "white_wool", - "orange_wool", - "magenta_wool", - "light_blue_wool", - "yellow_wool", - "lime_wool", - "pink_wool", - "gray_wool", - "light_gray_wool", - "cyan_wool", - "purple_wool", - "blue_wool", - "brown_wool", - "green_wool", - "red_wool", - "black_wool", -}, -/* 36 */ simple("moving_piston"), -/* 37 */ simple("dandelion"), -/* 38 */ { - "poppy", - "blue_orchid", - "allium", - "azure_bluet", - "red_tulip", - "orange_tulip", - "white_tulip", - "pink_tulip", - "oxeye_daisy", -}, -/* 39 */ simple("brown_mushroom"), -/* 40 */ simple("red_mushroom"), -/* 41 */ simple("gold_block"), -/* 42 */ simple("iron_block"), -/* 43 */ { - "smooth_stone_slab", - "sandstone_slab", - "oak_slab", - "cobblestone_slab", - "brick_slab", - "stone_brick_slab", - "nether_brick_slab", - "quartz_slab", -}, -/* 44 */ { - "smooth_stone_slab", - "sandstone_slab", - "oak_slab", - "cobblestone_slab", - "brick_slab", - "stone_brick_slab", - "nether_brick_slab", - "quartz_slab", - "stone_slab", - "sandstone_slab", - "oak_slab", - "cobblestone_slab", - "brick_slab", - "stone_brick_slab", - "nether_brick_slab", - "quartz_slab", -}, -/* 45 */ simple("bricks"), -/* 46 */ simple("tnt"), -/* 47 */ simple("bookshelf"), -/* 48 */ simple("mossy_cobblestone"), -/* 49 */ simple("obsidian"), -/* 50 */ { - nullptr, - "wall_torch", - "wall_torch", - "wall_torch", - "wall_torch", - "torch", -}, -/* 51 */ simple("fire"), -/* 52 */ simple("spawner"), -/* 53 */ simple("oak_stairs"), -/* 54 */ simple("chest"), -/* 55 */ simple("redstone_wire"), -/* 56 */ simple("diamond_ore"), -/* 57 */ simple("diamond_block"), -/* 58 */ simple("crafting_table"), -/* 59 */ simple("wheat"), -/* 60 */ simple("farmland"), -/* 61 */ simple("furnace"), -/* 62 */ simple("furnace"), -/* 63 */ simple("sign"), -/* 64 */ simple("oak_door"), -/* 65 */ simple("ladder"), -/* 66 */ simple("rail"), -/* 67 */ simple("cobblestone_stairs"), -/* 68 */ simple("wall_sign"), -/* 69 */ simple("lever"), -/* 70 */ simple("stone_pressure_plate"), -/* 71 */ simple("iron_door"), -/* 72 */ simple("oak_pressure_plate"), -/* 73 */ simple("redstone_ore"), -/* 74 */ simple("redstone_ore"), -/* 75 */ { - nullptr, - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_torch", -}, -/* 76 */ { - nullptr, - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_wall_torch", - "redstone_torch", -}, -/* 77 */ simple("stone_button"), -/* 78 */ simple("snow"), -/* 79 */ simple("ice"), -/* 80 */ simple("snow_block"), -/* 81 */ simple("cactus"), -/* 82 */ simple("clay"), -/* 83 */ simple("sugar_cane"), -/* 84 */ simple("jukebox"), -/* 85 */ simple("oak_fence"), -/* 86 */ simple("pumpkin"), -/* 87 */ simple("netherrack"), -/* 88 */ simple("soul_sand"), -/* 89 */ simple("glowstone"), -/* 90 */ simple("nether_portal"), -/* 91 */ simple("pumpkin"), -/* 92 */ simple("cake"), -/* 93 */ simple("repeater"), -/* 94 */ simple("repeater"), -/* 95 */ { - "white_stained_glass", - "orange_stained_glass", - "magenta_stained_glass", - "light_blue_stained_glass", - "yellow_stained_glass", - "lime_stained_glass", - "pink_stained_glass", - "gray_stained_glass", - "light_gray_stained_glass", - "cyan_stained_glass", - "purple_stained_glass", - "blue_stained_glass", - "brown_stained_glass", - "green_stained_glass", - "red_stained_glass", - "black_stained_glass", -}, -/* 96 */ simple("oak_trapdoor"), -/* 97 */ { - "infested_stone", - "infested_cobblestone", - "infested_stone_bricks", - "infested_mossy_stone_bricks", - "infested_cracked_stone_bricks", - "infested_chiseled_stone_bricks", -}, -/* 98 */ { - "stone_bricks", - "mossy_stone_bricks", - "cracked_stone_bricks", - "chiseled_stone_bricks", -}, -/* 99 */ simple("brown_mushroom_block"), -/* 100 */ simple("red_mushroom_block"), -/* 101 */ simple("iron_bars"), -/* 102 */ simple("glass_pane"), -/* 103 */ simple("melon"), -/* 104 */ simple("pumpkin_stem"), -/* 105 */ simple("melon_stem"), -/* 106 */ simple("vine"), -/* 107 */ simple("oak_fence_gate"), -/* 108 */ simple("brick_stairs"), -/* 109 */ simple("stone_brick_stairs"), -/* 110 */ simple("mycelium"), -/* 111 */ simple("lily_pad"), -/* 112 */ simple("nether_bricks"), -/* 113 */ simple("nether_brick_fence"), -/* 114 */ simple("nether_brick_stairs"), -/* 115 */ simple("nether_wart"), -/* 116 */ simple("enchanting_table"), -/* 117 */ simple("brewing_stand"), -/* 118 */ simple("cauldron"), -/* 119 */ simple("end_portal"), -/* 120 */ simple("end_portal_frame"), -/* 121 */ simple("end_stone"), -/* 122 */ simple("dragon_egg"), -/* 123 */ simple("redstone_lamp"), -/* 124 */ simple("redstone_lamp"), -/* 125 */ { - "oak_slab", - "spruce_slab", - "birch_slab", - "jungle_slab", - "acacia_slab", - "dark_oak_slab", -}, -/* 126 */ { - "oak_slab", - "spruce_slab", - "birch_slab", - "jungle_slab", - "acacia_slab", - "dark_oak_slab", - nullptr, - nullptr, - "oak_slab", - "spruce_slab", - "birch_slab", - "jungle_slab", - "acacia_slab", - "dark_oak_slab", -}, -/* 127 */ simple("cocoa"), -/* 128 */ simple("sandstone_stairs"), -/* 129 */ simple("emerald_ore"), -/* 130 */ simple("ender_chest"), -/* 131 */ simple("tripwire_hook"), -/* 132 */ simple("tripwire"), -/* 133 */ simple("emerald_block"), -/* 134 */ simple("spruce_stairs"), -/* 135 */ simple("birch_stairs"), -/* 136 */ simple("jungle_stairs"), -/* 137 */ simple("command_block"), -/* 138 */ simple("beacon"), -/* 139 */ { - "cobblestone_wall", - "mossy_cobblestone_wall", -}, -/* 140 */ simple("flower_pot"), -/* 141 */ simple("carrots"), -/* 142 */ simple("potatoes"), -/* 143 */ {}, -/* 144 */ {}, -/* 145 */ { - "anvil", - "anvil", - "anvil", - "anvil", - "chipped_anvil", - "chipped_anvil", - "chipped_anvil", - "chipped_anvil", - "damaged_anvil", - "damaged_anvil", - "damaged_anvil", - "damaged_anvil", -}, -/* 146 */ simple("trapped_chest"), -/* 147 */ simple("light_weighted_pressure_plate"), -/* 148 */ simple("heavy_weighted_pressure_plate"), -/* 149 */ simple("comparator"), -/* 150 */ simple("comparator"), -/* 151 */ simple("daylight_detector"), -/* 152 */ simple("redstone_block"), -/* 153 */ simple("nether_quartz_ore"), -/* 154 */ simple("hopper"), -/* 155 */ simple("quartz_block"), -/* 156 */ simple("quartz_stairs"), -/* 157 */ simple("activator_rail"), -/* 158 */ simple("dropper"), -/* 159 */ { - "white_terracotta", - "orange_terracotta", - "magenta_terracotta", - "light_blue_terracotta", - "yellow_terracotta", - "lime_terracotta", - "pink_terracotta", - "gray_terracotta", - "light_gray_terracotta", - "cyan_terracotta", - "purple_terracotta", - "blue_terracotta", - "brown_terracotta", - "green_terracotta", - "red_terracotta", - "black_terracotta", -}, -/* 160 */ { - "white_stained_glass_pane", - "orange_stained_glass_pane", - "magenta_stained_glass_pane", - "light_blue_stained_glass_pane", - "yellow_stained_glass_pane", - "lime_stained_glass_pane", - "pink_stained_glass_pane", - "gray_stained_glass_pane", - "light_gray_stained_glass_pane", - "cyan_stained_glass_pane", - "purple_stained_glass_pane", - "blue_stained_glass_pane", - "brown_stained_glass_pane", - "green_stained_glass_pane", - "red_stained_glass_pane", - "black_stained_glass_pane", -}, -/* 161 */ { - "acacia_leaves", - "dark_oak_leaves", - nullptr, - nullptr, - "acacia_leaves", - "dark_oak_leaves", - nullptr, - nullptr, - "acacia_leaves", - "dark_oak_leaves", - nullptr, - nullptr, - "acacia_leaves", - "dark_oak_leaves", -}, -/* 162 */ { - "acacia_log", - "dark_oak_log", - nullptr, - nullptr, - "acacia_log", - "dark_oak_log", - nullptr, - nullptr, - "acacia_log", - "dark_oak_log", - nullptr, - nullptr, - "acacia_log", - "dark_oak_log", -}, -/* 163 */ simple("acacia_stairs"), -/* 164 */ simple("dark_oak_stairs"), -/* 165 */ simple("slime_block"), -/* 166 */ simple("barrier"), -/* 167 */ simple("iron_trapdoor"), -/* 168 */ { - "prismarine", - "prismarine_bricks", - "dark_prismarine", -}, -/* 169 */ simple("sea_lantern"), -/* 170 */ simple("hay_block"), -/* 171 */ { - "white_carpet", - "orange_carpet", - "magenta_carpet", - "light_blue_carpet", - "yellow_carpet", - "lime_carpet", - "pink_carpet", - "gray_carpet", - "light_gray_carpet", - "cyan_carpet", - "purple_carpet", - "blue_carpet", - "brown_carpet", - "green_carpet", - "red_carpet", - "black_carpet", -}, -/* 172 */ simple("terracotta"), -/* 173 */ simple("coal_block"), -/* 174 */ simple("packed_ice"), -/* 175 */ { - "sunflower", - "lilac", - "tall_grass", - "large_fern", - "rose_bush", - "peony", -}, -/* 176 */ {/* banner */}, -/* 177 */ {/* wall banner */}, -/* 178 */ simple("daylight_detector"), -/* 179 */ simple("red_sandstone"), -/* 180 */ simple("red_sandstone_stairs"), -/* 181 */ simple("red_sandstone_slab"), -/* 182 */ simple("red_sandstone_slab"), -/* 183 */ simple("spruce_fence_gate"), -/* 184 */ simple("birch_fence_gate"), -/* 185 */ simple("jungle_fence_gate"), -/* 186 */ simple("dark_oak_fence_gate"), -/* 187 */ simple("acacia_fence_gate"), -/* 188 */ simple("spruce_fence"), -/* 189 */ simple("birch_fence"), -/* 190 */ simple("jungle_fence"), -/* 191 */ simple("dark_oak_fence"), -/* 192 */ simple("acacia_fence"), -/* 193 */ simple("spruce_door"), -/* 194 */ simple("birch_door"), -/* 195 */ simple("jungle_door"), -/* 196 */ simple("acacia_door"), -/* 197 */ simple("dark_oak_door"), -/* 198 */ simple("end_rod"), -/* 199 */ simple("chorus_plant"), -/* 200 */ simple("chorus_flower"), -/* 201 */ simple("purpur_block"), -/* 202 */ simple("purpur_pillar"), -/* 203 */ simple("purpur_stairs"), -/* 204 */ simple("purpur_slab"), -/* 205 */ simple("purpur_slab"), -/* 206 */ simple("end_stone_bricks"), -/* 207 */ simple("beetroots"), -/* 208 */ simple("grass_path"), -/* 209 */ simple("end_gateway"), -/* 210 */ simple("repeating_command_block"), -/* 211 */ simple("chain_command_block"), -/* 212 */ simple("frosted_ice"), -/* 213 */ simple("magma_block"), -/* 214 */ simple("nether_wart_block"), -/* 215 */ simple("red_nether_bricks"), -/* 216 */ simple("bone_block"), -/* 217 */ simple("structure_void"), -/* 218 */ simple("observer"), -/* 219 */ simple("white_shulker_box"), -/* 220 */ simple("orange_shulker_box"), -/* 221 */ simple("magenta_shulker_box"), -/* 222 */ simple("light_blue_shulker_box"), -/* 223 */ simple("yellow_shulker_box"), -/* 224 */ simple("lime_shulker_box"), -/* 225 */ simple("pink_shulker_box"), -/* 226 */ simple("gray_shulker_box"), -/* 227 */ simple("light_gray_shulker_box"), -/* 228 */ simple("cyan_shulker_box"), -/* 229 */ simple("purple_shulker_box"), -/* 230 */ simple("blue_shulker_box"), -/* 231 */ simple("brown_shulker_box"), -/* 232 */ simple("green_shulker_box"), -/* 233 */ simple("red_shulker_box"), -/* 234 */ simple("black_shulker_box"), -/* 235 */ simple("white_glazed_terracotta"), -/* 236 */ simple("orange_glazed_terracotta"), -/* 237 */ simple("magenta_glazed_terracotta"), -/* 238 */ simple("light_blue_glazed_terracotta"), -/* 239 */ simple("yellow_glazed_terracotta"), -/* 240 */ simple("lime_glazed_terracotta"), -/* 241 */ simple("pink_glazed_terracotta"), -/* 242 */ simple("gray_glazed_terracotta"), -/* 243 */ simple("light_gray_glazed_terracotta"), -/* 244 */ simple("cyan_glazed_terracotta"), -/* 245 */ simple("purple_glazed_terracotta"), -/* 246 */ simple("blue_glazed_terracotta"), -/* 247 */ simple("brown_glazed_terracotta"), -/* 248 */ simple("green_glazed_terracotta"), -/* 249 */ simple("red_glazed_terracotta"), -/* 250 */ simple("black_glazed_terracotta"), -/* 251 */ { - "white_concrete", - "orange_concrete", - "magenta_concrete", - "light_blue_concrete", - "yellow_concrete", - "lime_concrete", - "pink_concrete", - "gray_concrete", - "light_gray_concrete", - "cyan_concrete", - "purple_concrete", - "blue_concrete", - "brown_concrete", - "green_concrete", - "red_concrete", - "black_concrete", -}, -/* 252 */ { - "white_concrete_powder", - "orange_concrete_powder", - "magenta_concrete_powder", - "light_blue_concrete_powder", - "yellow_concrete_powder", - "lime_concrete_powder", - "pink_concrete_powder", - "gray_concrete_powder", - "light_gray_concrete_powder", - "cyan_concrete_powder", - "purple_concrete_powder", - "blue_concrete_powder", - "brown_concrete_powder", - "green_concrete_powder", - "red_concrete_powder", - "black_concrete_powder", -}, -/* 253 */ {}, -/* 254 */ {}, -/* 255 */ simple("structure_block"), diff --git a/src/UniqueCPtr.hpp b/src/UniqueCPtr.hpp deleted file mode 100644 index 743a712..0000000 --- a/src/UniqueCPtr.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include - -// UniqueCPtr is a wrapper around std::unique_ptr using std::free as its deallocator -// -// This allows to use it to manage memory allocated by C APIs (malloc, realloc, ...) -template class UniqueCPtr : public std::unique_ptr { -public: - UniqueCPtr() : std::unique_ptr(nullptr, std::free) {} - template UniqueCPtr(T2 ptr) : std::unique_ptr(ptr, std::free) {} -}; diff --git a/src/Util.hpp b/src/Util.hpp deleted file mode 100644 index 163813d..0000000 --- a/src/Util.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include -#include -#include -#include -#include - - -namespace MinedMap { - -template static inline T assertValue(T&& val) { - if (!val) - throw std::invalid_argument("assertValue failed"); - - return std::forward(val); -} - -static inline float clamp(float v, float min, float max) { - return std::max(std::min(v, max), min); -} - -// A block coordinate relative to a chunk/section (X/Y/Z) -typedef uint8_t block_idx_t; -// A section index in a chunk (Y) -typedef int8_t section_idx_t; -// A chunk coordinate relative to a region (X/Z) -typedef uint8_t chunk_idx_t; - -// A block coordinate relative to a region (X/Z) -typedef uint16_t region_block_idx_t; -// A block coordinate (Y) -typedef int16_t y_idx_t; - -const y_idx_t y_idx_min = std::numeric_limits::min(); - -} diff --git a/src/World/Block.hpp b/src/World/Block.hpp deleted file mode 100644 index e1ed09a..0000000 --- a/src/World/Block.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "../NBT/CompoundTag.hpp" -#include "../Resource/Biome.hpp" -#include "../Resource/BlockType.hpp" - - -namespace MinedMap { -namespace World { - -struct Block { - const Resource::BlockType *type; - y_idx_t depth; - uint8_t blockLight; - - bool isVisible() const { - return type && (type->flags & BLOCK_OPAQUE); - } - - Resource::FloatColor getColor(uint8_t biome) const { - if (!isVisible()) - return Resource::FloatColor {}; - - return (Resource::Biome::Biomes[biome] ?: Resource::Biome::Default)->getBlockColor(type, depth); - } - - operator bool() const { - return type; - } -}; - -} -} diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp deleted file mode 100644 index b9d27c5..0000000 --- a/src/World/Chunk.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#include "Chunk.hpp" -#include "../NBT/IntTag.hpp" -#include "../NBT/ListTag.hpp" -#include "../NBT/StringTag.hpp" - -#include -#include - - -namespace MinedMap { -namespace World { - -Chunk::Chunk(const ChunkData *data) { - std::shared_ptr sectionsTag; - - auto level = data->getRoot()->get("Level"); - if (level) { - sectionsTag = level->get("Sections"); - if (!sectionsTag || sectionsTag->empty()) - return; - - auto biomesIntArray = level->get("Biomes"); - auto biomesByteArray = level->get("Biomes"); - - if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY) { - biomeInts = std::move(biomesIntArray); - biomeFormat = INT_ARRAY; - } else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE) { - biomeInts = std::move(biomesIntArray); - biomeFormat = INT_ARRAY_PRE1_15; - } else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE) { - biomeBytes = std::move(biomesByteArray); - biomeFormat = BYTE_ARRAY; - } else { - throw std::invalid_argument("corrupt biome data"); - } - } else { - sectionsTag = data->getRoot()->get("sections"); - if (!sectionsTag || sectionsTag->empty()) - return; - - biomeFormat = SECTION; - } - - auto dataVersionTag = data->getRoot()->get("DataVersion"); - uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0; - - std::vector> tmpSections; - section_idx_t minY = std::numeric_limits::max(); - section_idx_t maxY = std::numeric_limits::min(); - - for (auto &sTag : *sectionsTag) { - auto s = std::dynamic_pointer_cast(sTag); - std::unique_ptr
section = Section::makeSection(s, dataVersion); - section_idx_t Y = section->getY(); - if (Y < minY) - minY = Y; - if (Y > maxY) - maxY = Y; - - tmpSections.push_back(std::move(section)); - } - - if (tmpSections.empty()) - return; - - assertValue(minY <= maxY); - sectionOffset = minY; - sections.resize(maxY - minY + 1); - - for (auto §ion : tmpSections) { - section_idx_t Y = section->getY(); - Y -= sectionOffset; - assertValue(Y >= 0 && size_t(Y) < sections.size()); - assertValue(!sections[Y]); - sections[Y] = std::move(section); - } -} - -uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { - if (x >= SIZE || z >= SIZE) - throw std::invalid_argument("getBiome: invalid block coordinate"); - - switch (biomeFormat) { - case INT_ARRAY: - if (y < 0 || y >= MAXY) - break; - return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT)); - case INT_ARRAY_PRE1_15: - return biomeInts->getValue(z*SIZE + x); - case BYTE_ARRAY: - return biomeBytes->getValue(z*SIZE + x); - case SECTION: { - section_idx_t Y = (y >> HSHIFT) - sectionOffset; - - if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y]) - break; - - return sections[Y]->getBiomeAt(x, y & HMASK, z); - } - default: - break; - } - - return 0xff; -} - -Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const { - Block block = {}; - - block.depth = height.depth; - - if (height.y == y_idx_min) - return block; - - section_idx_t Y = (height.y >> HSHIFT) - sectionOffset; - block_idx_t y = height.y & HMASK; - - if (Y >= 0 && size_t(Y) < sections.size() && sections[Y]) - block.type = sections[Y]->getBlockStateAt(x, y, z); - - section_idx_t Yt = ((height.y + 1) >> HSHIFT) - sectionOffset; - block_idx_t yt = (height.y + 1) & HMASK; - - if (Yt >= 0 && size_t(Yt) < sections.size() && sections[Yt]) - block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); - - return block; -} - -bool Chunk::getHeight( - Chunk::Height *height, const Section *section, - block_idx_t x, block_idx_t y, block_idx_t z, int flags -) const { - if (height->depth > y_idx_min) - return false; - - if (!(flags & WITH_DEPTH) && height->y > y_idx_min) - return false; - - const Resource::BlockType *type = section->getBlockStateAt(x, y, z); - if (!type || !(type->flags & BLOCK_OPAQUE)) - return false; - - if (height->y == y_idx_min) - height->y = (section->getY() << HSHIFT) + y; - - if (!(flags & WITH_DEPTH)) - return true; - - if (type->flags & BLOCK_WATER) - return false; - - height->depth = (section->getY() << HSHIFT) + y; - - return true; -} - -Chunk::Heightmap Chunk::getTopLayer(int flags) const { - uint32_t done = 0; - Heightmap ret; - - for (block_idx_t z = 0; z < SIZE; z++) { - for (block_idx_t x = 0; x < SIZE; x++) - ret.v[x][z] = Height { .y = y_idx_min, .depth = y_idx_min }; - } - - for (section_idx_t Y = sections.size() - 1; Y >= 0; Y--) { - if (done == SIZE*SIZE) - break; - - if (!sections[Y]) - continue; - - const Section *section = sections[Y].get(); - - for (int8_t y = SIZE-1; y >= 0; y--) { - if (done == SIZE*SIZE) - break; - - for (block_idx_t z = 0; z < SIZE; z++) { - for (block_idx_t x = 0; x < SIZE; x++) { - if (getHeight(&ret.v[x][z], section, x, y, z, flags)) - done++; - } - } - } - } - - return ret; -} - -} -} diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp deleted file mode 100644 index 611c3c8..0000000 --- a/src/World/Chunk.hpp +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - - -#include "Block.hpp" -#include "ChunkData.hpp" -#include "Section.hpp" -#include "../NBT/ByteArrayTag.hpp" -#include "../NBT/IntArrayTag.hpp" -#include "../Resource/BlockType.hpp" -#include "../Util.hpp" - -#include - - -namespace MinedMap { -namespace World { - -class Chunk { -public: - // Number of blocks in a chunk in x/z dimensions - static const uint32_t SIZE = Section::SIZE; - // Maximum Y value for pre-1.18 chunks - static const y_idx_t MAXY = 256; - - // Shift to get from height to section index - static const unsigned HSHIFT = 4; - // Mask to get from height to y index inside section - static const block_idx_t HMASK = 0xf; - - // Since Minecraft 1.15, biome information is stored for - // 4x4x4 block groups - static const unsigned BSHIFT = Section::BSHIFT; - // Number of biome values in a chunk in x/z dimensions - static const uint32_t BSIZE = Section::BSIZE; - // Number of biome values in a chunk in y dimension - static const uint32_t BMAXY = MAXY >> BSHIFT; - - // Flags - static const int WITH_DEPTH = (1 << 0); - - struct Height { - y_idx_t y; - y_idx_t depth; - }; - - struct Heightmap { - Height v[SIZE][SIZE]; - }; - -private: - section_idx_t sectionOffset; - std::vector> sections; - - enum BiomeFormat { - UNKNOWN = 0, - BYTE_ARRAY, - INT_ARRAY_PRE1_15, - INT_ARRAY, - SECTION, - } biomeFormat = UNKNOWN; - - std::shared_ptr biomeBytes; - std::shared_ptr biomeInts; - - bool getHeight( - Height *height, const Section *section, - block_idx_t x, block_idx_t y, block_idx_t z, int flags - ) const; - - const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const { - section_idx_t Y = (y >> HSHIFT) - sectionOffset; - - if (Y < 0 || size_t(Y) >= sections.size() || !sections[Y]) - return nullptr; - - return sections[Y]->getBlockStateAt(x, y & HMASK, z); - } - - -public: - Chunk(const ChunkData *data); - - uint8_t getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const; - Block getBlock(block_idx_t x, Height y, block_idx_t z) const; - - Heightmap getTopLayer(int flags) const; -}; - -} -} diff --git a/src/World/ChunkData.cpp b/src/World/ChunkData.cpp deleted file mode 100644 index 972ee5e..0000000 --- a/src/World/ChunkData.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2018, Matthias Schiffer - All rights reserved. -*/ - - -#include "ChunkData.hpp" - -#include -#include -#include - -#include - - -namespace MinedMap { -namespace World { - -ChunkData::ChunkData(Buffer buffer) { - size_t size = buffer.get32(); - - Buffer buffer2(buffer.get(size), size); - - uint8_t format = buffer2.get8(); - if (format != 2) - throw std::invalid_argument("unknown chunk format"); - - inflateChunk(buffer2); - parseChunk(); -} - -void ChunkData::inflateChunk(Buffer buffer) { - size_t outlen = 0; - uint8_t *output = nullptr; - - z_stream stream = {}; - int ret = inflateInit(&stream); - if (ret != Z_OK) - throw std::runtime_error("inflateInit() failed"); - - stream.avail_in = buffer.getRemaining(); - stream.next_in = const_cast(buffer.get(stream.avail_in)); - - while (stream.avail_in) { - outlen += 65536; - output = static_cast(std::realloc(output, outlen)); - - stream.next_out = output + stream.total_out; - stream.avail_out = outlen - stream.total_out; - - ret = inflate(&stream, Z_NO_FLUSH); - switch (ret) { - case Z_NEED_DICT: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&stream); - throw std::runtime_error("inflate() failed"); - } - } - - inflateEnd(&stream); - - len = stream.total_out; - data = UniqueCPtr(output); -} - -void ChunkData::parseChunk() { - Buffer nbt(data.get(), len); - std::pair> tag = NBT::Tag::readNamedTag(&nbt); - if (!tag.first.empty()) - throw std::invalid_argument("invalid root tag"); - - root = assertValue(std::dynamic_pointer_cast(tag.second)); -} - -} -} diff --git a/src/World/ChunkData.hpp b/src/World/ChunkData.hpp deleted file mode 100644 index 62a69c1..0000000 --- a/src/World/ChunkData.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2018, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - - -#include "../Buffer.hpp" -#include "../UniqueCPtr.hpp" -#include "../Util.hpp" -#include "../NBT/CompoundTag.hpp" - -#include - - -namespace MinedMap { -namespace World { - -class ChunkData { -private: - size_t len; - UniqueCPtr data; - - std::shared_ptr root; - - void inflateChunk(Buffer buffer); - void parseChunk(); - -public: - ChunkData(Buffer buffer); - - const std::shared_ptr & getRoot() const { - return root; - } -}; - -} -} diff --git a/src/World/Level.cpp b/src/World/Level.cpp deleted file mode 100644 index ec7d25a..0000000 --- a/src/World/Level.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#include "Level.hpp" -#include "../GZip.hpp" -#include "../Util.hpp" -#include "../NBT/IntTag.hpp" - - -namespace MinedMap { -namespace World { - -Level::Level(const char *filename) { - buffer = readGZip(filename); - - Buffer nbt(buffer.data(), buffer.size()); - std::pair> tag = NBT::Tag::readNamedTag(&nbt); - if (tag.first != "") - throw std::invalid_argument("invalid root tag"); - - root = assertValue(std::dynamic_pointer_cast(tag.second)); - data = assertValue(root->get("Data")); -} - -std::pair Level::getSpawn() const { - int32_t x = assertValue(data->get("SpawnX"))->getValue(); - int32_t z = assertValue(data->get("SpawnZ"))->getValue(); - - return std::make_pair(x, z); -} - -} -} diff --git a/src/World/Level.hpp b/src/World/Level.hpp deleted file mode 100644 index dd40513..0000000 --- a/src/World/Level.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "../NBT/CompoundTag.hpp" - -#include -#include - - -namespace MinedMap { -namespace World { - -class Level { -private: - std::vector buffer; - - std::shared_ptr root; - std::shared_ptr data; - -public: - Level(const char *filename); - - std::pair getSpawn() const; -}; - -} -} diff --git a/src/World/Region.cpp b/src/World/Region.cpp deleted file mode 100644 index cd21e6d..0000000 --- a/src/World/Region.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#include "Region.hpp" - -#include -#include -#include - - -namespace MinedMap { -namespace World { - -Region::ChunkMap Region::processHeader(const uint8_t header[4096]) { - ChunkMap map; - - for (chunk_idx_t z = 0; z < 32; z++) { - for (chunk_idx_t x = 0; x < 32; x++) { - const uint8_t *p = &header[128*z + x*4]; - - uint32_t offset = (p[0] << 16) | (p[1] << 8) | p[2]; - - if (!offset) - continue; - - uint8_t len = p[3]; - - map.emplace(offset, ChunkDesc(x, z, len)); - } - } - - return map; -} - -void Region::visitChunks(const char *filename, const ChunkVisitor &visitor) { - std::ifstream file; - file.exceptions(std::ios::badbit); - file.open(filename, std::ios::in | std::ios::binary); - - ChunkMap chunkMap; - - { - uint8_t header[4096]; - file.read((char *)header, sizeof(header)); - - chunkMap = processHeader(header); - } - - bool seen[SIZE][SIZE] = {}; - - size_t i = 1, c = 0; - while (!file.eof() && !file.fail()) { - auto it = chunkMap.find(i); - if (it == chunkMap.end()) { - file.ignore(4096); - i++; - continue; - } - - chunk_idx_t x = std::get<0>(it->second); - chunk_idx_t z = std::get<1>(it->second); - size_t len = std::get<2>(it->second); - - if (seen[x][z]) - throw std::invalid_argument("duplicate chunk"); - - seen[x][z] = true; - c++; - - uint8_t buffer[len * 4096]; - std::memset(buffer, 0, sizeof(buffer)); - file.read((char *)buffer, len * 4096); - - ChunkData chunk(Buffer(buffer, len * 4096)); - visitor(x, z, &chunk); - - i += len; - } - - if (c != chunkMap.size()) - throw std::invalid_argument("region incomplete"); -} - -} -} diff --git a/src/World/Region.hpp b/src/World/Region.hpp deleted file mode 100644 index 22840e8..0000000 --- a/src/World/Region.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - -#include "Chunk.hpp" - -#include -#include -#include -#include -#include - - -namespace MinedMap { -namespace World { - -class Region { -public: - // Number of chunks in a region in each dimension - static const uint32_t SIZE = 32; - - typedef std::function ChunkVisitor; - - Region() = delete; - -private: - typedef std::tuple ChunkDesc; - typedef std::unordered_map ChunkMap; - - static ChunkMap processHeader(const uint8_t header[4096]); - -public: - static void visitChunks(const char *filename, const ChunkVisitor &visitor); -}; - -} -} diff --git a/src/World/Section.cpp b/src/World/Section.cpp deleted file mode 100644 index ba7b0c9..0000000 --- a/src/World/Section.cpp +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#include "Section.hpp" -#include "../Resource/Biome.hpp" -#include "../NBT/ByteTag.hpp" -#include "../NBT/IntTag.hpp" -#include "../NBT/StringTag.hpp" - -#include - - -namespace MinedMap { -namespace World { - -Section::Section(const std::shared_ptr §ion) { - const std::shared_ptr YByteTag = section->get("Y"); - if (YByteTag) { - Y = int8_t(YByteTag->getValue()); - } else { - const std::shared_ptr YIntTag = assertValue(section->get("Y")); - int32_t value = YIntTag->getValue(); - if (int8_t(value) != value) - throw std::invalid_argument("unsupported section Y coordinate"); - Y = value; - } - blockLight = section->get("BlockLight"); -} - -const Resource::BlockType * Section::getBlockStateAt(block_idx_t, block_idx_t, block_idx_t) const { - return nullptr; -} - -uint8_t Section::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - return 0xff; -} - -std::unique_ptr
Section::makeSection(const std::shared_ptr §ion, uint32_t dataVersion) { - { - const std::shared_ptr blockStates = section->get("block_states"); - if (blockStates) { - const std::shared_ptr palette = assertValue(blockStates->get("palette")); - std::shared_ptr data = blockStates->get("data"); - - const std::shared_ptr biomes = assertValue(section->get("biomes")); - const std::shared_ptr biomePalette = assertValue(biomes->get("palette")); - std::shared_ptr biomeData = biomes->get("data"); - - return std::unique_ptr
(new PaletteSection( - section, std::move(data), palette, std::move(biomeData), biomePalette, dataVersion - )); - } - } - - { - std::shared_ptr blockStates = section->get("BlockStates"); - if (blockStates) { - const std::shared_ptr palette = assertValue(section->get("Palette")); - - return std::unique_ptr
(new PaletteSection( - section, std::move(blockStates), palette, - std::shared_ptr(), std::shared_ptr(), dataVersion - )); - } - } - - { - std::shared_ptr blocks = section->get("Blocks"); - if (blocks) { - std::shared_ptr data = assertValue(section->get("Data")); - - return std::unique_ptr
(new LegacySection(section, std::move(blocks), std::move(data))); - } - } - - return std::unique_ptr
(new Section(section)); -} - - -const Resource::BlockType * LegacySection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - uint8_t type = getBlockAt(x, y, z); - uint8_t data = getDataAt(x, y, z); - - return Resource::LEGACY_BLOCK_TYPES.types[type][data]; -} - - -const Resource::BlockType * PaletteSection::lookup(const std::string &name, uint32_t dataVersion) { - if (dataVersion < 1900 && name == "minecraft:stone_slab") - return Resource::BlockType::lookup("minecraft:smooth_stone_slab"); - - return Resource::BlockType::lookup(name); -} - -PaletteSection::PaletteSection( - const std::shared_ptr §ion, - std::shared_ptr &&blockStates0, - const std::shared_ptr &paletteData, - std::shared_ptr &&biomes0, - const std::shared_ptr &biomePaletteData, - uint32_t dataVersion0 -) : Section(section), blockStates(blockStates0), biomes(biomes0), dataVersion(dataVersion0) { - bits = 4; - while ((1u << bits) < paletteData->size()) { - bits++; - - if (bits > 12) - throw std::invalid_argument("unsupported block palette size"); - } - - biomeBits = 1; - if (biomePaletteData) { - while ((1u << biomeBits) < biomePaletteData->size()) { - biomeBits++; - - if (biomeBits > 6) - throw std::invalid_argument("unsupported biome palette size"); - } - } - - unsigned expectedLength; - - if (dataVersion < 2529) { - expectedLength = 64 * bits; - } else { - unsigned blocksPerWord = (64 / bits); - expectedLength = (4096 + blocksPerWord - 1) / blocksPerWord; - } - - if (blockStates && blockStates->getLength() != expectedLength) - throw std::invalid_argument("corrupt section block data"); - - unsigned biomesPerWord = (64 / biomeBits); - unsigned expectedBiomeLength = (64 + biomesPerWord - 1) / biomesPerWord; - - if (biomes && biomes->getLength() != expectedBiomeLength) - throw std::invalid_argument("corrupt section biome data"); - - for (const auto &entry : *paletteData) { - const NBT::CompoundTag &paletteEntry = *assertValue(dynamic_cast(entry.get())); - std::string name = assertValue(paletteEntry.get("Name"))->getValue(); - - const Resource::BlockType *type = lookup(name, dataVersion); - if (!type) - std::fprintf(stderr, "Warning: unknown block type: %s\n", name.c_str()); - - palette.push_back(type); - } - - if (biomePaletteData) { - for (const auto &entry : *biomePaletteData) { - const NBT::StringTag &paletteEntry = - *assertValue(dynamic_cast(entry.get())); - std::string name = paletteEntry.getValue(); - - auto it = Resource::Biome::Names.find(name); - uint8_t biome; - if (it != Resource::Biome::Names.end()) { - biome = it->second; - } else { - std::fprintf(stderr, "Warning: unknown biome: %s\n", name.c_str()); - biome = 0xff; - } - - biomePalette.push_back(biome); - } - } -} - -const Resource::BlockType * PaletteSection::getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - if (!blockStates) - return palette.at(0); - - size_t index = getIndex(x, y, z); - size_t bitIndex; - - if (dataVersion < 2529) { - bitIndex = bits * index; - } else { - unsigned blocksPerWord = (64 / bits); - size_t word = index / blocksPerWord; - bitIndex = 64 * word + bits * (index % blocksPerWord); - } - - size_t pos = bitIndex >> 3; - unsigned shift = bitIndex & 7; - uint16_t mask = (1u << bits) - 1; - - uint32_t v = blockStates->getPointer()[mangleByteIndex(pos)]; - - if (shift + bits > 8) - v |= blockStates->getPointer()[mangleByteIndex(pos + 1)] << 8; - if (shift + bits > 16) - v |= blockStates->getPointer()[mangleByteIndex(pos + 2)] << 16; - /* We do not need to check for shift+bits > 24: bits should never - be greater than 12, so our value will never span more than 3 bytes */ - - return palette.at((v >> shift) & mask); -} - -uint8_t PaletteSection::getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - if (!biomes) - return biomePalette.at(0); - - size_t index = getBiomeIndex(x, y, z); - - unsigned biomesPerWord = (64 / biomeBits); - size_t word = index / biomesPerWord; - size_t bitIndex = 64 * word + biomeBits * (index % biomesPerWord); - - size_t pos = bitIndex >> 3; - unsigned shift = bitIndex & 7; - uint16_t mask = (1u << biomeBits) - 1; - - uint32_t v = biomes->getPointer()[mangleByteIndex(pos)]; - - if (shift + biomeBits > 8) - v |= biomes->getPointer()[mangleByteIndex(pos + 1)] << 8; - /* We do not need to check for shift+bits > 16: biomeBits should never - be greater than 6, so our value will never span more than 2 bytes */ - - return biomePalette.at((v >> shift) & mask); -} - -} -} diff --git a/src/World/Section.hpp b/src/World/Section.hpp deleted file mode 100644 index 9884a77..0000000 --- a/src/World/Section.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2015-2021, Matthias Schiffer - All rights reserved. -*/ - - -#pragma once - - -#include "../NBT/ByteArrayTag.hpp" -#include "../NBT/CompoundTag.hpp" -#include "../NBT/ListTag.hpp" -#include "../NBT/LongArrayTag.hpp" -#include "../Resource/BlockType.hpp" -#include "../Util.hpp" - -#include -#include - - -namespace MinedMap { -namespace World { - -class Section { -public: - // Number of blocks in a section in each dimension - static const uint32_t SIZE = 16; - - // Since Minecraft 1.15, biome information is stored for - // 4x4x4 block groups - static const unsigned BSHIFT = 2; - // Number of biome values in a chunk in x/z dimensions - static const uint32_t BSIZE = SIZE >> BSHIFT; - - -private: - section_idx_t Y; - std::shared_ptr blockLight; - -protected: - static size_t getIndex(block_idx_t x, block_idx_t y, block_idx_t z) { - if (x >= SIZE || y >= SIZE || z >= SIZE) - throw std::range_error("Section::getIndex(): bad coordinates"); - - return SIZE*SIZE*y + SIZE*z + x; - } - - static size_t getBiomeIndex(block_idx_t x, block_idx_t y, block_idx_t z) { - if (x >= SIZE || y >= SIZE || z >= SIZE) - throw std::range_error("Section::getBiomeIndex(): bad coordinates"); - - return BSIZE*BSIZE*(y>>BSHIFT) + BSIZE*(z>>BSHIFT) + (x>>BSHIFT); - } - - static uint8_t getHalf(const uint8_t *v, block_idx_t x, block_idx_t y, block_idx_t z) { - size_t i = getIndex(x, y, z); - - if (i % 2) - return (v[i/2] >> 4); - else - return (v[i/2] & 0xf); - } - - Section(const std::shared_ptr §ion); - -public: - virtual ~Section() {} - - section_idx_t getY() const { return Y; }; - - virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; - virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const; - - uint8_t getBlockLightAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - if (!blockLight) - return 0; - - return getHalf(blockLight->getPointer(), x, y, z); - } - - static std::unique_ptr
makeSection(const std::shared_ptr §ion, uint32_t dataVersion); -}; - -class LegacySection : public Section { -private: - std::shared_ptr blocks; - std::shared_ptr data; - - - uint8_t getBlockAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - return blocks->getValue(getIndex(x, y, z)); - } - - uint8_t getDataAt(block_idx_t x, block_idx_t y, block_idx_t z) const { - return getHalf(data->getPointer(), x, y, z); - } - -public: - LegacySection( - const std::shared_ptr §ion, - std::shared_ptr &&blocks0, - std::shared_ptr &&data0 - ) : Section(section), blocks(blocks0), data(data0) {} - - virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; -}; - -class PaletteSection : public Section { -private: - std::shared_ptr blockStates; - std::vector palette; - unsigned bits; - - std::shared_ptr biomes; - std::vector biomePalette; - unsigned biomeBits; - - uint32_t dataVersion; - - static const Resource::BlockType * lookup(const std::string &name, uint32_t dataVersion); - - static size_t mangleByteIndex(size_t index) { - return (index & ~(size_t)7) + 7 - (index & 7); - } - -public: - PaletteSection( - const std::shared_ptr §ion, - std::shared_ptr &&blockStates0, - const std::shared_ptr &paletteData, - std::shared_ptr &&biomes0, - const std::shared_ptr &biomePaletteData, - uint32_t dataVersion0 - ); - - virtual const Resource::BlockType * getBlockStateAt(block_idx_t x, block_idx_t y, block_idx_t z) const; - virtual uint8_t getBiomeAt(block_idx_t x, block_idx_t y, block_idx_t z) const; -}; - -} -} diff --git a/src/nbtdump.cpp b/src/nbtdump.cpp deleted file mode 100644 index d47b15e..0000000 --- a/src/nbtdump.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2018, Matthias Schiffer - All rights reserved. -*/ - - -#include "Buffer.hpp" -#include "GZip.hpp" -#include "Util.hpp" -#include "NBT/Tag.hpp" - -#include -#include -#include - - -int main(int argc, char *argv[]) { - using namespace MinedMap; - - if (argc != 2) { - std::fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - std::vector buffer = readGZip(argv[1]); - - Buffer nbt(buffer.data(), buffer.size()); - std::pair> tag = NBT::Tag::readNamedTag(&nbt); - if (tag.first != "") - throw std::invalid_argument("invalid root tag"); - - std::cout << *tag.second << std::endl; - - return 0; -} diff --git a/src/regiondump.cpp b/src/regiondump.cpp deleted file mode 100644 index 62fe359..0000000 --- a/src/regiondump.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2018-2021, Matthias Schiffer - All rights reserved. -*/ - - -#include "Buffer.hpp" -#include "GZip.hpp" -#include "Util.hpp" -#include "NBT/Tag.hpp" -#include "World/Region.hpp" - -#include -#include - - -int main(int argc, char *argv[]) { - using namespace MinedMap; - - if (argc != 2) { - std::fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - World::Region::visitChunks(argv[1], [&] (chunk_idx_t X, chunk_idx_t Z, const World::ChunkData *chunk) { - std::cout << "Chunk(" << unsigned(X) << ", " << unsigned(Z) << "): " - << *chunk->getRoot() << std::endl; - }); - - return 0; -} From 40105aaccd9b8a1a1b8d0e89368ba830ccba3dcc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 24 Jan 2023 18:52:44 +0100 Subject: [PATCH 046/460] Initial Rust setup --- .gitignore | 3 +-- Cargo.lock | 7 +++++++ Cargo.toml | 9 +++++++++ rustfmt.toml | 1 + src/main.rs | 3 +++ 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 rustfmt.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index a8d69d5..73d8961 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ /viewer/data /resource/data /resource/colors.json -.idea/ -cmake-build-debug/ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..418de4f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "minedmap" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d981c31 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "minedmap" +version = "0.1.0" +edition = "2021" +license = "BSD-2-Clause" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..218e203 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +hard_tabs = true diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a30eb95 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From ddd78079dcd8d2b0fa65030ea27db57ee2b36702 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 24 Jan 2023 20:39:54 +0100 Subject: [PATCH 047/460] Add new nbtdump util --- Cargo.lock | 418 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 + TODO.md | 8 + src/bin/nbtdump.rs | 30 ++++ 4 files changed, 460 insertions(+) create mode 100644 TODO.md create mode 100644 src/bin/nbtdump.rs diff --git a/Cargo.lock b/Cargo.lock index 418de4f..c7a31f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,424 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastnbt" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da8cfe3db6e587f39487b01dae75222c5fa809342f6aa4b8310d17b53e666728" +dependencies = [ + "byteorder", + "cesu8", + "serde", + "serde_bytes", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "minedmap" version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "fastnbt", + "flate2", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "once_cell" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[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.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/Cargo.toml b/Cargo.toml index d981c31..25eb4e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,7 @@ license = "BSD-2-Clause" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0.68" +clap = { version = "4.1.4", features = ["derive"] } +fastnbt = "2.3.2" +flate2 = "1.0.25" diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..e6c14f6 --- /dev/null +++ b/TODO.md @@ -0,0 +1,8 @@ +# TODO + +## Optimizations + +- To check: + - fastnbt borrow + - fastnbt from_reader + - flate2 backends diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs new file mode 100644 index 0000000..20236f7 --- /dev/null +++ b/src/bin/nbtdump.rs @@ -0,0 +1,30 @@ +use std::{fs::File, io::prelude::*, path::PathBuf}; + +use anyhow::{Context, Result}; +use clap::Parser; +use flate2::read::GzDecoder; + +#[derive(Debug, Parser)] +struct Args { + /// Filename to dump + file: PathBuf, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + let file = File::open(&args.file).context("Failed to open file")?; + + let mut decoder = GzDecoder::new(file); + let mut buf = vec![]; + decoder + .read_to_end(&mut buf) + .context("Failed to read file")?; + + let nbt: fastnbt::Value = + fastnbt::from_bytes(buf.as_slice()).context("Failed to decode NBT data")?; + + println!("{:#x?}", nbt); + + Ok(()) +} From 5a364e243457fa9c5634f37ac84b44d113722665 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 25 Jan 2023 19:08:23 +0100 Subject: [PATCH 048/460] Add new regiondump implemention --- Cargo.lock | 1 + Cargo.toml | 1 + src/bin/regiondump.rs | 147 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 src/bin/regiondump.rs diff --git a/Cargo.lock b/Cargo.lock index c7a31f8..3cf2b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,7 @@ dependencies = [ "clap", "fastnbt", "flate2", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 25eb4e2..977525b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ anyhow = "1.0.68" clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" flate2 = "1.0.25" +serde = "1.0.152" diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs new file mode 100644 index 0000000..d0e27ce --- /dev/null +++ b/src/bin/regiondump.rs @@ -0,0 +1,147 @@ +use std::{ + collections::HashMap, + fs::File, + io::{prelude::*, SeekFrom}, + path::PathBuf, +}; + +use anyhow::{bail, Context, Result}; +use clap::Parser; +use flate2::read::ZlibDecoder; +use serde::de::DeserializeOwned; + +const BLOCKSIZE: usize = 4096; +const CHUNKS_PER_REGION: u8 = 32; + +/// A chunk X coordinate relative to a region +#[derive(Debug, Clone, Copy)] +pub struct ChunkX(pub u8); + +/// A chunk Z coordinate relative to a region +#[derive(Debug, Clone, Copy)] +pub struct ChunkZ(pub u8); + +#[derive(Debug)] +struct ChunkDesc { + x: ChunkX, + z: ChunkZ, + len: u8, +} + +fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { + let mut map = HashMap::new(); + + for z in 0..CHUNKS_PER_REGION { + for x in 0..CHUNKS_PER_REGION { + let chunk = + &header[(4 * (usize::from(CHUNKS_PER_REGION) * usize::from(z) + usize::from(x)))..]; + + let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); + if offset == 0 { + continue; + } + + let len = chunk[3]; + + map.insert( + offset, + ChunkDesc { + x: ChunkX(x), + z: ChunkZ(z), + len, + }, + ); + } + } + + map +} + +fn decode_chunk(buf: &[u8]) -> Result +where + T: DeserializeOwned, +{ + let (len_bytes, buf) = buf.split_at(4); + let len = u32::from_be_bytes( + len_bytes + .try_into() + .context("Failed to decode chunk size")?, + ) as usize; + + let buf = &buf[..len]; + let (format, buf) = buf.split_at(1); + if format.get(0) != Some(&2) { + bail!("Unknown chunk format"); + } + + let mut decoder = ZlibDecoder::new(&buf[..]); + let mut decode_buffer = vec![]; + decoder + .read_to_end(&mut decode_buffer) + .context("Failed to decompress chunk data")?; + + fastnbt::from_bytes(&decode_buffer).context("Failed to decode NBT data") +} + +fn foreach_chunk(mut reader: R, mut f: F) -> Result<()> +where + R: Read + Seek, + T: DeserializeOwned, + F: FnMut(ChunkX, ChunkZ, T), +{ + let chunk_map = { + let mut header = [0u8; BLOCKSIZE]; + reader + .read_exact(&mut header) + .context("Failed to read region header")?; + + parse_header(&header) + }; + + let mut index = 1; + let mut count = 0; + let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; + + while count < chunk_map.len() { + let Some(&ChunkDesc { x, z, len }) = chunk_map.get(&index) else { + reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; + index += 1; + continue; + }; + + let chunk_seen = &mut seen[x.0 as usize][z.0 as usize]; + if *chunk_seen { + bail!("Duplicate chunk"); + } + + *chunk_seen = true; + count += 1; + + let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; + reader + .read_exact(&mut buffer[..]) + .context("Failed to read chunk data")?; + + f(x, z, decode_chunk(&buffer[..])?); + + index += len as u32; + } + + Ok(()) +} + +#[derive(Debug, Parser)] +struct Args { + /// Filename to dump + file: PathBuf, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + let mut file = File::open(&args.file).context("Failed to open file")?; + + foreach_chunk(&mut file, |x, z, value: fastnbt::Value| { + println!("Chunk({}, {}): {:#x?}", x.0, z.0, value); + }) +} From 5e96be3fda14fe87941c4e7fcc51cfae881b7e11 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 25 Jan 2023 21:41:08 +0100 Subject: [PATCH 049/460] Refactor logic from new dump tools into library crate --- Cargo.toml | 1 + src/bin/nbtdump.rs | 19 ++---- src/bin/regiondump.rs | 135 +------------------------------------- src/io/data.rs | 28 ++++++++ src/io/mod.rs | 2 + src/io/region.rs | 147 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + src/types.rs | 9 +++ 8 files changed, 196 insertions(+), 147 deletions(-) create mode 100644 src/io/data.rs create mode 100644 src/io/mod.rs create mode 100644 src/io/region.rs create mode 100644 src/lib.rs create mode 100644 src/types.rs diff --git a/Cargo.toml b/Cargo.toml index 977525b..b704512 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ name = "minedmap" version = "0.1.0" edition = "2021" license = "BSD-2-Clause" +default-run = "minedmap" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index 20236f7..b2f287e 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -1,8 +1,7 @@ -use std::{fs::File, io::prelude::*, path::PathBuf}; +use std::path::PathBuf; -use anyhow::{Context, Result}; +use anyhow::Result; use clap::Parser; -use flate2::read::GzDecoder; #[derive(Debug, Parser)] struct Args { @@ -13,18 +12,8 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let file = File::open(&args.file).context("Failed to open file")?; - - let mut decoder = GzDecoder::new(file); - let mut buf = vec![]; - decoder - .read_to_end(&mut buf) - .context("Failed to read file")?; - - let nbt: fastnbt::Value = - fastnbt::from_bytes(buf.as_slice()).context("Failed to decode NBT data")?; - - println!("{:#x?}", nbt); + let value: fastnbt::Value = minedmap::io::data::from_file(&args.file)?; + println!("{:#x?}", value); Ok(()) } diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index d0e27ce..1a3b216 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -1,134 +1,7 @@ -use std::{ - collections::HashMap, - fs::File, - io::{prelude::*, SeekFrom}, - path::PathBuf, -}; +use std::path::PathBuf; -use anyhow::{bail, Context, Result}; +use anyhow::Result; use clap::Parser; -use flate2::read::ZlibDecoder; -use serde::de::DeserializeOwned; - -const BLOCKSIZE: usize = 4096; -const CHUNKS_PER_REGION: u8 = 32; - -/// A chunk X coordinate relative to a region -#[derive(Debug, Clone, Copy)] -pub struct ChunkX(pub u8); - -/// A chunk Z coordinate relative to a region -#[derive(Debug, Clone, Copy)] -pub struct ChunkZ(pub u8); - -#[derive(Debug)] -struct ChunkDesc { - x: ChunkX, - z: ChunkZ, - len: u8, -} - -fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { - let mut map = HashMap::new(); - - for z in 0..CHUNKS_PER_REGION { - for x in 0..CHUNKS_PER_REGION { - let chunk = - &header[(4 * (usize::from(CHUNKS_PER_REGION) * usize::from(z) + usize::from(x)))..]; - - let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); - if offset == 0 { - continue; - } - - let len = chunk[3]; - - map.insert( - offset, - ChunkDesc { - x: ChunkX(x), - z: ChunkZ(z), - len, - }, - ); - } - } - - map -} - -fn decode_chunk(buf: &[u8]) -> Result -where - T: DeserializeOwned, -{ - let (len_bytes, buf) = buf.split_at(4); - let len = u32::from_be_bytes( - len_bytes - .try_into() - .context("Failed to decode chunk size")?, - ) as usize; - - let buf = &buf[..len]; - let (format, buf) = buf.split_at(1); - if format.get(0) != Some(&2) { - bail!("Unknown chunk format"); - } - - let mut decoder = ZlibDecoder::new(&buf[..]); - let mut decode_buffer = vec![]; - decoder - .read_to_end(&mut decode_buffer) - .context("Failed to decompress chunk data")?; - - fastnbt::from_bytes(&decode_buffer).context("Failed to decode NBT data") -} - -fn foreach_chunk(mut reader: R, mut f: F) -> Result<()> -where - R: Read + Seek, - T: DeserializeOwned, - F: FnMut(ChunkX, ChunkZ, T), -{ - let chunk_map = { - let mut header = [0u8; BLOCKSIZE]; - reader - .read_exact(&mut header) - .context("Failed to read region header")?; - - parse_header(&header) - }; - - let mut index = 1; - let mut count = 0; - let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; - - while count < chunk_map.len() { - let Some(&ChunkDesc { x, z, len }) = chunk_map.get(&index) else { - reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; - index += 1; - continue; - }; - - let chunk_seen = &mut seen[x.0 as usize][z.0 as usize]; - if *chunk_seen { - bail!("Duplicate chunk"); - } - - *chunk_seen = true; - count += 1; - - let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; - reader - .read_exact(&mut buffer[..]) - .context("Failed to read chunk data")?; - - f(x, z, decode_chunk(&buffer[..])?); - - index += len as u32; - } - - Ok(()) -} #[derive(Debug, Parser)] struct Args { @@ -139,9 +12,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let mut file = File::open(&args.file).context("Failed to open file")?; - - foreach_chunk(&mut file, |x, z, value: fastnbt::Value| { + minedmap::io::region::from_file(&args.file)?.foreach_chunk(|x, z, value: fastnbt::Value| { println!("Chunk({}, {}): {:#x?}", x.0, z.0, value); }) } diff --git a/src/io/data.rs b/src/io/data.rs new file mode 100644 index 0000000..a4e08b7 --- /dev/null +++ b/src/io/data.rs @@ -0,0 +1,28 @@ +use std::{fs::File, io::prelude::*, path::Path}; + +use anyhow::{Context, Result}; +use flate2::read::GzDecoder; +use serde::de::DeserializeOwned; + +pub fn from_reader(reader: R) -> Result +where + R: Read, + T: DeserializeOwned, +{ + let mut decoder = GzDecoder::new(reader); + let mut buf = vec![]; + decoder + .read_to_end(&mut buf) + .context("Failed to read file")?; + + fastnbt::from_bytes(&buf[..]).context("Failed to decode NBT data") +} + +pub fn from_file(path: P) -> Result +where + P: AsRef, + T: DeserializeOwned, +{ + let file = File::open(path).context("Failed to open file")?; + from_reader(file) +} diff --git a/src/io/mod.rs b/src/io/mod.rs new file mode 100644 index 0000000..f109d15 --- /dev/null +++ b/src/io/mod.rs @@ -0,0 +1,2 @@ +pub mod data; +pub mod region; diff --git a/src/io/region.rs b/src/io/region.rs new file mode 100644 index 0000000..fad020c --- /dev/null +++ b/src/io/region.rs @@ -0,0 +1,147 @@ +use std::{ + collections::HashMap, + fs::File, + io::{prelude::*, SeekFrom}, + path::Path, +}; + +use anyhow::{bail, Context, Result}; +use flate2::read::ZlibDecoder; +use serde::de::DeserializeOwned; + +use crate::types::*; + +const BLOCKSIZE: usize = 4096; + +#[derive(Debug)] +struct ChunkDesc { + x: ChunkX, + z: ChunkZ, + len: u8, +} + +fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { + let mut map = HashMap::new(); + + for z in 0..CHUNKS_PER_REGION { + for x in 0..CHUNKS_PER_REGION { + let chunk = + &header[(4 * (usize::from(CHUNKS_PER_REGION) * usize::from(z) + usize::from(x)))..]; + + let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); + if offset == 0 { + continue; + } + + let len = chunk[3]; + + map.insert( + offset, + ChunkDesc { + x: ChunkX(x), + z: ChunkZ(z), + len, + }, + ); + } + } + + map +} + +fn decode_chunk(buf: &[u8]) -> Result +where + T: DeserializeOwned, +{ + let (len_bytes, buf) = buf.split_at(4); + let len = u32::from_be_bytes( + len_bytes + .try_into() + .context("Failed to decode chunk size")?, + ) as usize; + + let buf = &buf[..len]; + let (format, buf) = buf.split_at(1); + if format.get(0) != Some(&2) { + bail!("Unknown chunk format"); + } + + let mut decoder = ZlibDecoder::new(&buf[..]); + let mut decode_buffer = vec![]; + decoder + .read_to_end(&mut decode_buffer) + .context("Failed to decompress chunk data")?; + + fastnbt::from_bytes(&decode_buffer).context("Failed to decode NBT data") +} + +#[derive(Debug)] +pub struct Region { + reader: R, +} + +impl Region { + pub fn foreach_chunk(self, mut f: F) -> Result<()> + where + R: Read + Seek, + T: DeserializeOwned, + F: FnMut(ChunkX, ChunkZ, T), + { + let Region { mut reader } = self; + + let chunk_map = { + let mut header = [0u8; BLOCKSIZE]; + reader + .read_exact(&mut header) + .context("Failed to read region header")?; + + parse_header(&header) + }; + + let mut index = 1; + let mut count = 0; + let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; + + while count < chunk_map.len() { + let Some(&ChunkDesc { x, z, len }) = chunk_map.get(&index) else { + reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; + index += 1; + continue; + }; + + let chunk_seen = &mut seen[x.0 as usize][z.0 as usize]; + if *chunk_seen { + bail!("Duplicate chunk"); + } + + *chunk_seen = true; + count += 1; + + let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; + reader + .read_exact(&mut buffer[..]) + .context("Failed to read chunk data")?; + + f(x, z, decode_chunk(&buffer[..])?); + + index += len as u32; + } + + Ok(()) + } +} + +pub fn from_reader(reader: R) -> Region +where + R: Read + Seek, +{ + Region { reader } +} + +pub fn from_file

(path: P) -> Result> +where + P: AsRef, +{ + let file = File::open(path).context("Failed to open file")?; + Ok(from_reader(file)) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..146b296 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod io; +pub mod types; diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..54593a4 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,9 @@ +pub const CHUNKS_PER_REGION: u8 = 32; + +/// A chunk X coordinate relative to a region +#[derive(Debug, Clone, Copy)] +pub struct ChunkX(pub u8); + +/// A chunk Z coordinate relative to a region +#[derive(Debug, Clone, Copy)] +pub struct ChunkZ(pub u8); From 0d8b989c101655ede9934bfbf53728459f533bbe Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 25 Jan 2023 21:47:17 +0100 Subject: [PATCH 050/460] io/region: remove count variable from Region::foreach_chunk() --- src/io/region.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index fad020c..f2347bb 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -89,7 +89,7 @@ impl Region { { let Region { mut reader } = self; - let chunk_map = { + let mut chunk_map = { let mut header = [0u8; BLOCKSIZE]; reader .read_exact(&mut header) @@ -99,11 +99,10 @@ impl Region { }; let mut index = 1; - let mut count = 0; let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; - while count < chunk_map.len() { - let Some(&ChunkDesc { x, z, len }) = chunk_map.get(&index) else { + while !chunk_map.is_empty() { + let Some(ChunkDesc { x, z, len }) = chunk_map.remove(&index) else { reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; index += 1; continue; @@ -113,9 +112,7 @@ impl Region { if *chunk_seen { bail!("Duplicate chunk"); } - *chunk_seen = true; - count += 1; let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; reader From 48e03aa2668f3f689ae155d65338b8e317ba1001 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 27 Jan 2023 21:21:09 +0100 Subject: [PATCH 051/460] Introduce ChunkCoords type --- src/bin/regiondump.rs | 4 ++-- src/io/region.rs | 17 +++++++++-------- src/types.rs | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 1a3b216..3b68881 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -12,7 +12,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - minedmap::io::region::from_file(&args.file)?.foreach_chunk(|x, z, value: fastnbt::Value| { - println!("Chunk({}, {}): {:#x?}", x.0, z.0, value); + minedmap::io::region::from_file(&args.file)?.foreach_chunk(|coords, value: fastnbt::Value| { + println!("Chunk {:?}: {:#x?}", coords, value); }) } diff --git a/src/io/region.rs b/src/io/region.rs index f2347bb..ec42d3c 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -15,8 +15,7 @@ const BLOCKSIZE: usize = 4096; #[derive(Debug)] struct ChunkDesc { - x: ChunkX, - z: ChunkZ, + coords: ChunkCoords, len: u8, } @@ -38,8 +37,10 @@ fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { map.insert( offset, ChunkDesc { - x: ChunkX(x), - z: ChunkZ(z), + coords: ChunkCoords { + x: ChunkX(x), + z: ChunkZ(z), + }, len, }, ); @@ -85,7 +86,7 @@ impl Region { where R: Read + Seek, T: DeserializeOwned, - F: FnMut(ChunkX, ChunkZ, T), + F: FnMut(ChunkCoords, T), { let Region { mut reader } = self; @@ -102,13 +103,13 @@ impl Region { let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; while !chunk_map.is_empty() { - let Some(ChunkDesc { x, z, len }) = chunk_map.remove(&index) else { + let Some(ChunkDesc { coords, len }) = chunk_map.remove(&index) else { reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; index += 1; continue; }; - let chunk_seen = &mut seen[x.0 as usize][z.0 as usize]; + let chunk_seen = &mut seen[coords.x.0 as usize][coords.z.0 as usize]; if *chunk_seen { bail!("Duplicate chunk"); } @@ -119,7 +120,7 @@ impl Region { .read_exact(&mut buffer[..]) .context("Failed to read chunk data")?; - f(x, z, decode_chunk(&buffer[..])?); + f(coords, decode_chunk(&buffer[..])?); index += len as u32; } diff --git a/src/types.rs b/src/types.rs index 54593a4..7fb8649 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + pub const CHUNKS_PER_REGION: u8 = 32; /// A chunk X coordinate relative to a region @@ -7,3 +9,16 @@ pub struct ChunkX(pub u8); /// A chunk Z coordinate relative to a region #[derive(Debug, Clone, Copy)] pub struct ChunkZ(pub u8); + +/// A pair of chunk coordinates relative to a region +#[derive(Clone, Copy)] +pub struct ChunkCoords { + pub x: ChunkX, + pub z: ChunkZ, +} + +impl Debug for ChunkCoords { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {})", self.x.0, self.z.0) + } +} From 28b22ce4238a68fa551358d65320389d90c7f86d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 27 Jan 2023 21:51:54 +0100 Subject: [PATCH 052/460] Introduce ChunkArray type A generic array for per-chunk data, indexed by ChunkCoords. --- Cargo.lock | 16 ++++++++++++++++ Cargo.toml | 1 + src/io/region.rs | 39 ++++++++++++++------------------------- src/types.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cf2b24..e1222a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + [[package]] name = "errno" version = "0.2.8" @@ -170,6 +176,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "libc" version = "0.2.139" @@ -190,6 +205,7 @@ dependencies = [ "clap", "fastnbt", "flate2", + "itertools", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index b704512..6ab5984 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ anyhow = "1.0.68" clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" flate2 = "1.0.25" +itertools = "0.10.5" serde = "1.0.152" diff --git a/src/io/region.rs b/src/io/region.rs index ec42d3c..909e548 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -22,29 +22,19 @@ struct ChunkDesc { fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { let mut map = HashMap::new(); - for z in 0..CHUNKS_PER_REGION { - for x in 0..CHUNKS_PER_REGION { - let chunk = - &header[(4 * (usize::from(CHUNKS_PER_REGION) * usize::from(z) + usize::from(x)))..]; + for coords in ChunkArray::<()>::keys() { + let chunk = &header[(4 + * (usize::from(CHUNKS_PER_REGION) * usize::from(coords.z.0) + + usize::from(coords.x.0)))..]; - let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); - if offset == 0 { - continue; - } - - let len = chunk[3]; - - map.insert( - offset, - ChunkDesc { - coords: ChunkCoords { - x: ChunkX(x), - z: ChunkZ(z), - }, - len, - }, - ); + let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); + if offset == 0 { + continue; } + + let len = chunk[3]; + + map.insert(offset, ChunkDesc { coords, len }); } map @@ -100,7 +90,7 @@ impl Region { }; let mut index = 1; - let mut seen = [[false; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]; + let mut seen = ChunkArray::::default(); while !chunk_map.is_empty() { let Some(ChunkDesc { coords, len }) = chunk_map.remove(&index) else { @@ -109,11 +99,10 @@ impl Region { continue; }; - let chunk_seen = &mut seen[coords.x.0 as usize][coords.z.0 as usize]; - if *chunk_seen { + if seen[coords] { bail!("Duplicate chunk"); } - *chunk_seen = true; + seen[coords] = true; let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; reader diff --git a/src/types.rs b/src/types.rs index 7fb8649..9aa4b7d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,4 +1,9 @@ -use std::fmt::Debug; +use std::{ + fmt::Debug, + ops::{Index, IndexMut}, +}; + +use itertools::iproduct; pub const CHUNKS_PER_REGION: u8 = 32; @@ -22,3 +27,37 @@ impl Debug for ChunkCoords { write!(f, "({}, {})", self.x.0, self.z.0) } } + +#[derive(Debug, Clone, Copy, Default)] +pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]); + +impl ChunkArray { + pub fn keys() -> impl Iterator { + iproduct!(0..CHUNKS_PER_REGION, 0..CHUNKS_PER_REGION).map(|(z, x)| ChunkCoords { + x: ChunkX(x), + z: ChunkZ(z), + }) + } + + pub fn values(&self) -> impl Iterator { + Self::keys().map(|k| &self[k]) + } + + pub fn iter(&self) -> impl Iterator { + Self::keys().map(|k| (k, &self[k])) + } +} + +impl Index for ChunkArray { + type Output = T; + + fn index(&self, index: ChunkCoords) -> &Self::Output { + &self.0[index.z.0 as usize][index.x.0 as usize] + } +} + +impl IndexMut for ChunkArray { + fn index_mut(&mut self, index: ChunkCoords) -> &mut Self::Output { + &mut self.0[index.z.0 as usize][index.x.0 as usize] + } +} From daa188eb1d7aee7db9ebe0203a2e45c6e4cdc4e9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 27 Jan 2023 22:12:02 +0100 Subject: [PATCH 053/460] io/region: use ChunkArray to parse region header A layout of a ChunkArray:: matches the binary format of the region header. --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/io/region.rs | 16 +++++++--------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1222a5..c45a502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bytemuck" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" + [[package]] name = "byteorder" version = "1.4.3" @@ -202,6 +208,7 @@ name = "minedmap" version = "0.1.0" dependencies = [ "anyhow", + "bytemuck", "clap", "fastnbt", "flate2", diff --git a/Cargo.toml b/Cargo.toml index 6ab5984..1ed267a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ default-run = "minedmap" [dependencies] anyhow = "1.0.68" +bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" flate2 = "1.0.25" diff --git a/src/io/region.rs b/src/io/region.rs index 909e548..332f2cd 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -19,20 +19,18 @@ struct ChunkDesc { len: u8, } -fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap { +fn parse_header(header: &ChunkArray) -> HashMap { let mut map = HashMap::new(); - for coords in ChunkArray::<()>::keys() { - let chunk = &header[(4 - * (usize::from(CHUNKS_PER_REGION) * usize::from(coords.z.0) - + usize::from(coords.x.0)))..]; + for (coords, &chunk) in header.iter() { + let offset_len = u32::from_be(chunk); - let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); + let offset = offset_len >> 8; if offset == 0 { continue; } - let len = chunk[3]; + let len = offset_len as u8; map.insert(offset, ChunkDesc { coords, len }); } @@ -81,9 +79,9 @@ impl Region { let Region { mut reader } = self; let mut chunk_map = { - let mut header = [0u8; BLOCKSIZE]; + let mut header = ChunkArray::::default(); reader - .read_exact(&mut header) + .read_exact(bytemuck::cast_mut::<_, [u8; BLOCKSIZE]>(&mut header.0)) .context("Failed to read region header")?; parse_header(&header) From 3cdafa7be965117bbb48a85c1632b60fc0f89754 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 27 Jan 2023 23:01:01 +0100 Subject: [PATCH 054/460] Fix clippy warnings --- src/bin/nbtdump.rs | 2 +- src/bin/regiondump.rs | 8 +++++--- src/io/region.rs | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index b2f287e..d944cf2 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -12,7 +12,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let value: fastnbt::Value = minedmap::io::data::from_file(&args.file)?; + let value: fastnbt::Value = minedmap::io::data::from_file(args.file.as_path())?; println!("{:#x?}", value); Ok(()) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 3b68881..5663a80 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -12,7 +12,9 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - minedmap::io::region::from_file(&args.file)?.foreach_chunk(|coords, value: fastnbt::Value| { - println!("Chunk {:?}: {:#x?}", coords, value); - }) + minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( + |coords, value: fastnbt::Value| { + println!("Chunk {:?}: {:#x?}", coords, value); + }, + ) } diff --git a/src/io/region.rs b/src/io/region.rs index 332f2cd..df5578a 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -51,11 +51,11 @@ where let buf = &buf[..len]; let (format, buf) = buf.split_at(1); - if format.get(0) != Some(&2) { + if !matches!(format, [2]) { bail!("Unknown chunk format"); } - let mut decoder = ZlibDecoder::new(&buf[..]); + let mut decoder = ZlibDecoder::new(buf); let mut decode_buffer = vec![]; decoder .read_to_end(&mut decode_buffer) From da8ac506d9e407533cf11ff243a1571c7a0913df Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 28 Jan 2023 00:58:47 +0100 Subject: [PATCH 055/460] io: remove a few unnecessary [..] for Vec -> slice deref --- src/io/data.rs | 2 +- src/io/region.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/io/data.rs b/src/io/data.rs index a4e08b7..d475465 100644 --- a/src/io/data.rs +++ b/src/io/data.rs @@ -15,7 +15,7 @@ where .read_to_end(&mut buf) .context("Failed to read file")?; - fastnbt::from_bytes(&buf[..]).context("Failed to decode NBT data") + fastnbt::from_bytes(&buf).context("Failed to decode NBT data") } pub fn from_file(path: P) -> Result diff --git a/src/io/region.rs b/src/io/region.rs index df5578a..1f02017 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -104,10 +104,10 @@ impl Region { let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; reader - .read_exact(&mut buffer[..]) + .read_exact(&mut buffer) .context("Failed to read chunk data")?; - f(coords, decode_chunk(&buffer[..])?); + f(coords, decode_chunk(&buffer)?); index += len as u32; } From 7c7e36f6bee2544afdc9fe7eec12fc6beb27b880 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jan 2023 00:53:48 +0100 Subject: [PATCH 056/460] io/region: avoid panic for invalid chunk lengths --- src/io/region.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index 1f02017..7602c62 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -26,12 +26,12 @@ fn parse_header(header: &ChunkArray) -> HashMap { let offset_len = u32::from_be(chunk); let offset = offset_len >> 8; - if offset == 0 { + let len = offset_len as u8; + + if offset == 0 || len == 0 { continue; } - let len = offset_len as u8; - map.insert(offset, ChunkDesc { coords, len }); } @@ -49,7 +49,11 @@ where .context("Failed to decode chunk size")?, ) as usize; + if len < 1 || len > buf.len() { + bail!("Invalid chunk size"); + } let buf = &buf[..len]; + let (format, buf) = buf.split_at(1); if !matches!(format, [2]) { bail!("Unknown chunk format"); From 1d126ba7712279ad00245a8e74e9ae4075223624 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jan 2023 17:04:28 +0100 Subject: [PATCH 057/460] io/region: remove error handling for impossible cases from decode_chunk() --- src/io/region.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index 7602c62..97dadcc 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -43,11 +43,7 @@ where T: DeserializeOwned, { let (len_bytes, buf) = buf.split_at(4); - let len = u32::from_be_bytes( - len_bytes - .try_into() - .context("Failed to decode chunk size")?, - ) as usize; + let len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize; if len < 1 || len > buf.len() { bail!("Invalid chunk size"); @@ -55,7 +51,7 @@ where let buf = &buf[..len]; let (format, buf) = buf.split_at(1); - if !matches!(format, [2]) { + if format[0] != 2 { bail!("Unknown chunk format"); } From 92a9bb3bb3f16092aae9239a80d0539a9211e633 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 Jan 2023 17:08:39 +0100 Subject: [PATCH 058/460] io/region: add chunk coords to error descriptions --- src/io/region.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index 97dadcc..ac9784b 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -98,16 +98,18 @@ impl Region { }; if seen[coords] { - bail!("Duplicate chunk"); + bail!("Duplicate chunk {:?}", coords); } seen[coords] = true; let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; reader .read_exact(&mut buffer) - .context("Failed to read chunk data")?; + .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))?; - f(coords, decode_chunk(&buffer)?); + f(coords, chunk); index += len as u32; } From 6186a0d916dfbb9e62b94bf291d6fb266a079ca5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jan 2023 00:45:05 +0100 Subject: [PATCH 059/460] io/region: accept incomplete block for final chunk --- src/io/region.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index ac9784b..b75fcef 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -42,14 +42,6 @@ fn decode_chunk(buf: &[u8]) -> Result where T: DeserializeOwned, { - let (len_bytes, buf) = buf.split_at(4); - let len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize; - - if len < 1 || len > buf.len() { - bail!("Invalid chunk size"); - } - let buf = &buf[..len]; - let (format, buf) = buf.split_at(1); if format[0] != 2 { bail!("Unknown chunk format"); @@ -92,7 +84,6 @@ impl Region { while !chunk_map.is_empty() { let Some(ChunkDesc { coords, len }) = chunk_map.remove(&index) else { - reader.seek(SeekFrom::Current(BLOCKSIZE as i64)).context("Failed to seek chunk data")?; index += 1; continue; }; @@ -102,7 +93,20 @@ impl Region { } seen[coords] = true; - let mut buffer = vec![0; (len as usize) * BLOCKSIZE]; + reader + .seek(SeekFrom::Start(index as u64 * BLOCKSIZE as u64)) + .context("Failed to seek chunk data")?; + + let mut len_buf = [0u8; 4]; + reader + .read_exact(&mut len_buf) + .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); + } + + let mut buffer = vec![0; byte_len]; reader .read_exact(&mut buffer) .with_context(|| format!("Failed to read data for chunk {:?}", coords))?; From 8c34f74952bbc2ecddbd74164b78808e850f3e39 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 30 Jan 2023 19:08:51 +0100 Subject: [PATCH 060/460] io/region: return sorted Vec instead of HashMap from parse_header() Instead of counting and looking up indices in the HashMap, we can just iterate over all offsets in the returned Vec. --- src/io/region.rs | 54 ++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/io/region.rs b/src/io/region.rs index b75fcef..93ff42b 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -1,5 +1,4 @@ use std::{ - collections::HashMap, fs::File, io::{prelude::*, SeekFrom}, path::Path, @@ -15,27 +14,35 @@ const BLOCKSIZE: usize = 4096; #[derive(Debug)] struct ChunkDesc { - coords: ChunkCoords, + offset: u32, len: u8, + coords: ChunkCoords, } -fn parse_header(header: &ChunkArray) -> HashMap { - let mut map = HashMap::new(); +fn parse_header(header: &ChunkArray) -> Vec { + let mut chunks: Vec<_> = header + .iter() + .filter_map(|(coords, &chunk)| { + let offset_len = u32::from_be(chunk); - for (coords, &chunk) in header.iter() { - let offset_len = u32::from_be(chunk); + let offset = offset_len >> 8; + let len = offset_len as u8; - let offset = offset_len >> 8; - let len = offset_len as u8; + if offset == 0 || len == 0 { + return None; + } - if offset == 0 || len == 0 { - continue; - } + Some(ChunkDesc { + offset, + len, + coords, + }) + }) + .collect(); - map.insert(offset, ChunkDesc { coords, len }); - } + chunks.sort_by_key(|chunk| chunk.offset); - map + chunks } fn decode_chunk(buf: &[u8]) -> Result @@ -70,7 +77,7 @@ impl Region { { let Region { mut reader } = self; - let mut chunk_map = { + let chunks = { let mut header = ChunkArray::::default(); reader .read_exact(bytemuck::cast_mut::<_, [u8; BLOCKSIZE]>(&mut header.0)) @@ -79,22 +86,21 @@ impl Region { parse_header(&header) }; - let mut index = 1; let mut seen = ChunkArray::::default(); - while !chunk_map.is_empty() { - let Some(ChunkDesc { coords, len }) = chunk_map.remove(&index) else { - index += 1; - continue; - }; - + for ChunkDesc { + offset, + len, + coords, + } in chunks + { if seen[coords] { bail!("Duplicate chunk {:?}", coords); } seen[coords] = true; reader - .seek(SeekFrom::Start(index as u64 * BLOCKSIZE as u64)) + .seek(SeekFrom::Start(offset as u64 * BLOCKSIZE as u64)) .context("Failed to seek chunk data")?; let mut len_buf = [0u8; 4]; @@ -114,8 +120,6 @@ impl Region { .with_context(|| format!("Failed to decode data for chunk {:?}", coords))?; f(coords, chunk); - - index += len as u32; } Ok(()) From 63794722822ba35c8037d261e1f36114f5cd56d5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 28 Jan 2023 22:29:12 +0100 Subject: [PATCH 061/460] world/de: new module for deserialization data structures The new structures contain only the fields that MinedMap needs. --- src/lib.rs | 1 + src/main.rs | 21 +++++++++- src/world/de.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++ src/world/mod.rs | 1 + 4 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/world/de.rs create mode 100644 src/world/mod.rs diff --git a/src/lib.rs b/src/lib.rs index 146b296..54ea8b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod io; pub mod types; +pub mod world; diff --git a/src/main.rs b/src/main.rs index a30eb95..2f104ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,20 @@ -fn main() { - println!("Hello, world!"); +use std::path::PathBuf; + +use anyhow::Result; +use clap::Parser; + +#[derive(Debug, Parser)] +struct Args { + /// Filename to dump + file: PathBuf, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( + |coords, value: minedmap::world::de::Chunk| { + println!("Chunk {:?}: {:#?}", coords, value); + }, + ) } diff --git a/src/world/de.rs b/src/world/de.rs new file mode 100644 index 0000000..ead4687 --- /dev/null +++ b/src/world/de.rs @@ -0,0 +1,101 @@ +//! Data structures used to deserialize Minecraft save data + +use serde::Deserialize; + +/// Element of the `palette` list of 1.18+ [block states](BlockStatesV1_18) +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct BlockStatePaletteEntry { + pub name: String, +} + +/// 1.18+ `block_states` element found in a [section](SectionV1_18) +#[derive(Debug, Deserialize)] +pub struct BlockStatesV1_18 { + pub palette: Vec, + pub data: Option, +} + +/// 1.18+ `biomes` element found in a [section](SectionV1_18) +#[derive(Debug, Deserialize)] +pub struct BiomesV1_18 { + pub palette: Vec, + pub data: Option, +} + +/// Element of the 1.18+ `sections` list found in a [Chunk] +#[derive(Debug, Deserialize)] +pub struct SectionV1_18 { + #[serde(rename = "Y")] + pub y: i32, + pub block_states: BlockStatesV1_18, + pub biomes: BiomesV1_18, + #[serde(rename = "BlockLight")] + pub block_light: Option, +} + +/// Version-specific part of a pre-1.18 [Section](SectionOld) +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum SectionOldVariants { + #[serde(rename_all = "PascalCase")] + V1_13 { + block_states: fastnbt::LongArray, + palette: Vec, + }, + #[serde(rename_all = "PascalCase")] + Old { + blocks: fastnbt::ByteArray, + data: fastnbt::ByteArray, + }, + Empty {}, +} + +/// Pre-1.18 section element found in the [Level](LevelOld) compound +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct SectionOld { + pub y: i8, + pub block_light: Option, + #[serde(flatten)] + pub section: SectionOldVariants, +} + +/// Pre-1.18 biome fields found in the [Level](LevelOld) compound +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum BiomesOld { + IntArray(fastnbt::IntArray), + ByteArray(fastnbt::ByteArray), +} + +/// `Level` compound element found in pre-1.18 [chunks](Chunk) +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct LevelOld { + #[serde(default)] + pub sections: Vec, + pub biomes: Option, +} + +/// Version-specific part of a [Chunk] compound +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum ChunkVariants { + V1_18 { + sections: Vec, + }, + #[serde(rename_all = "PascalCase")] + Old { + level: LevelOld, + }, +} + +/// Toplevel compound element of a Minecraft chunk +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Chunk { + pub data_version: Option, + #[serde(flatten)] + pub chunk: ChunkVariants, +} diff --git a/src/world/mod.rs b/src/world/mod.rs new file mode 100644 index 0000000..7bbc60f --- /dev/null +++ b/src/world/mod.rs @@ -0,0 +1 @@ +pub mod de; From 718ecf59093a2249f6675573699c3f3acd637cff Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 7 Feb 2023 22:09:14 +0100 Subject: [PATCH 062/460] resource: update block type code generator for Rust --- Cargo.lock | 21 + Cargo.toml | 1 + resource/generate.py | 28 +- src/lib.rs | 1 + src/resource/block_types.rs | 6327 +++++++++++++++++++++++++++++++++++ src/resource/mod.rs | 33 + 6 files changed, 6399 insertions(+), 12 deletions(-) create mode 100644 src/resource/block_types.rs create mode 100644 src/resource/mod.rs diff --git a/Cargo.lock b/Cargo.lock index c45a502..8d40e13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,26 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "enumflags2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "errno" version = "0.2.8" @@ -210,6 +230,7 @@ dependencies = [ "anyhow", "bytemuck", "clap", + "enumflags2", "fastnbt", "flate2", "itertools", diff --git a/Cargo.toml b/Cargo.toml index 1ed267a..1b43110 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ default-run = "minedmap" anyhow = "1.0.68" bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } +enumflags2 = "0.7.5" fastnbt = "2.3.2" flate2 = "1.0.25" itertools = "0.10.5" diff --git a/resource/generate.py b/resource/generate.py index de1f828..7e6ee09 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -6,7 +6,7 @@ import sys if len(sys.argv) != 3: - sys.exit('Usage: extract.py ') + sys.exit('Usage: extract.py ') with open(sys.argv[1]) as f: colors = json.load(f) @@ -14,29 +14,33 @@ with open(sys.argv[1]) as f: output = {} with open(sys.argv[2], 'w') as f: + print('use enumflags2::make_bitflags;', file=f); + print('', file=f) + print('use super::*;', file=f) + print('', file=f) + print('pub const BLOCK_TYPES: &[(&str, BlockType)] = &[', file=f) + for name, info in colors.items(): flags = [] if info['opaque']: - flags.append('BLOCK_OPAQUE') + flags.append('Opaque') if info['grass']: - flags.append('BLOCK_GRASS') + flags.append('Grass') if info['foliage']: - flags.append('BLOCK_FOLIAGE') + flags.append('Foliage') if info['birch']: - flags.append('BLOCK_BIRCH') + flags.append('Birch') if info['spruce']: - flags.append('BLOCK_SPRUCE') + flags.append('Spruce') if info['water']: - flags.append('BLOCK_WATER') - if flags: - flags = '|'.join(flags) - else: - flags = '0' + flags.append('Water') + flags = 'make_bitflags!(BlockFlags::{' + '|'.join(flags) + '})' - print('{"%s", {%s, {%u, %u, %u}}},' % ( + print('\t("%s", BlockType { flags: %s, color: BlockColor(%u, %u, %u) }),' % ( name, flags, info['color']['r'], info['color']['g'], info['color']['b'], ), file=f) + print('];', file=f) diff --git a/src/lib.rs b/src/lib.rs index 54ea8b7..8342ba8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ pub mod io; +pub mod resource; pub mod types; pub mod world; diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs new file mode 100644 index 0000000..94d1e2b --- /dev/null +++ b/src/resource/block_types.rs @@ -0,0 +1,6327 @@ +use enumflags2::make_bitflags; + +use super::*; + +pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ + ( + "minecraft:acacia_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:acacia_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(167, 95, 60), + }, + ), + ( + "minecraft:acacia_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + color: BlockColor(149, 148, 148), + }, + ), + ( + "minecraft:acacia_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(150, 88, 55), + }, + ), + ( + "minecraft:acacia_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(118, 117, 23), + }, + ), + ( + "minecraft:acacia_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 90, 50), + }, + ), + ( + "minecraft:acacia_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(156, 87, 51), + }, + ), + ( + "minecraft:acacia_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:acacia_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 96, 86), + }, + ), + ( + "minecraft:activator_rail", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 87, 74), + }, + ), + ( + "minecraft:air", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:allium", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:amethyst_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(133, 97, 191), + }, + ), + ( + "minecraft:amethyst_cluster", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(163, 126, 207), + }, + ), + ( + "minecraft:ancient_debris", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(94, 66, 58), + }, + ), + ( + "minecraft:andesite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 136, 136), + }, + ), + ( + "minecraft:andesite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 136, 136), + }, + ), + ( + "minecraft:andesite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 136, 136), + }, + ), + ( + "minecraft:andesite_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 136, 136), + }, + ), + ( + "minecraft:anvil", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 72), + }, + ), + ( + "minecraft:attached_melon_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(141, 142, 141), + }, + ), + ( + "minecraft:attached_pumpkin_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(139, 139, 139), + }, + ), + ( + "minecraft:azalea", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 124, 47), + }, + ), + ( + "minecraft:azalea_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(90, 114, 44), + }, + ), + ( + "minecraft:azure_bluet", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:bamboo", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 144, 19), + }, + ), + ( + "minecraft:bamboo_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:barrel", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(134, 100, 58), + }, + ), + ( + "minecraft:barrier", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:basalt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 81, 86), + }, + ), + ( + "minecraft:beacon", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(117, 220, 215), + }, + ), + ( + "minecraft:bedrock", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(85, 85, 85), + }, + ), + ( + "minecraft:bee_nest", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(202, 160, 74), + }, + ), + ( + "minecraft:beehive", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(180, 146, 90), + }, + ), + ( + "minecraft:beetroots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 91, 30), + }, + ), + ( + "minecraft:bell", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(253, 235, 110), + }, + ), + ( + "minecraft:big_dripleaf", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(111, 141, 51), + }, + ), + ( + "minecraft:big_dripleaf_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:birch_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:birch_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(220, 209, 176), + }, + ), + ( + "minecraft:birch_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Birch}), + color: BlockColor(130, 129, 130), + }, + ), + ( + "minecraft:birch_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(193, 179, 135), + }, + ), + ( + "minecraft:birch_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 160, 79), + }, + ), + ( + "minecraft:birch_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 175, 121), + }, + ), + ( + "minecraft:birch_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(207, 194, 157), + }, + ), + ( + "minecraft:birch_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:birch_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(216, 215, 210), + }, + ), + ( + "minecraft:black_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:black_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:black_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:black_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:black_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 21, 25), + }, + ), + ( + "minecraft:black_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(8, 10, 15), + }, + ), + ( + "minecraft:black_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(25, 26, 31), + }, + ), + ( + "minecraft:black_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(67, 30, 32), + }, + ), + ( + "minecraft:black_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(25, 25, 29), + }, + ), + ( + "minecraft:black_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(25, 25, 25), + }, + ), + ( + "minecraft:black_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(24, 24, 24), + }, + ), + ( + "minecraft:black_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(37, 22, 16), + }, + ), + ( + "minecraft:black_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:black_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 21, 25), + }, + ), + ( + "minecraft:blackstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(42, 36, 41), + }, + ), + ( + "minecraft:blackstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(42, 36, 41), + }, + ), + ( + "minecraft:blackstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(42, 36, 41), + }, + ), + ( + "minecraft:blackstone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(42, 36, 41), + }, + ), + ( + "minecraft:blast_furnace", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 80, 81), + }, + ), + ( + "minecraft:blue_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:blue_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:blue_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:blue_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:blue_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 57, 157), + }, + ), + ( + "minecraft:blue_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 46, 143), + }, + ), + ( + "minecraft:blue_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(70, 73, 166), + }, + ), + ( + "minecraft:blue_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 64, 139), + }, + ), + ( + "minecraft:blue_ice", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(116, 167, 253), + }, + ), + ( + "minecraft:blue_orchid", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:blue_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 45, 140), + }, + ), + ( + "minecraft:blue_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(51, 76, 178), + }, + ), + ( + "minecraft:blue_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(48, 73, 171), + }, + ), + ( + "minecraft:blue_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(74, 59, 91), + }, + ), + ( + "minecraft:blue_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:blue_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 57, 157), + }, + ), + ( + "minecraft:bone_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(209, 206, 179), + }, + ), + ( + "minecraft:bookshelf", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:brain_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brain_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(207, 91, 159), + }, + ), + ( + "minecraft:brain_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brain_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brewing_stand", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(123, 101, 81), + }, + ), + ( + "minecraft:brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(150, 97, 83), + }, + ), + ( + "minecraft:brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(150, 97, 83), + }, + ), + ( + "minecraft:brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(150, 97, 83), + }, + ), + ( + "minecraft:bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(150, 97, 83), + }, + ), + ( + "minecraft:brown_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brown_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brown_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brown_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:brown_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 71, 40), + }, + ), + ( + "minecraft:brown_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(96, 59, 31), + }, + ), + ( + "minecraft:brown_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 84, 53), + }, + ), + ( + "minecraft:brown_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(119, 106, 85), + }, + ), + ( + "minecraft:brown_mushroom", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brown_mushroom_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 111, 81), + }, + ), + ( + "minecraft:brown_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(106, 66, 35), + }, + ), + ( + "minecraft:brown_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(102, 76, 51), + }, + ), + ( + "minecraft:brown_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(97, 73, 48), + }, + ), + ( + "minecraft:brown_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 51, 35), + }, + ), + ( + "minecraft:brown_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:brown_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 71, 40), + }, + ), + ( + "minecraft:bubble_column", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Water}), + color: BlockColor(177, 177, 177), + }, + ), + ( + "minecraft:bubble_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:bubble_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(165, 26, 162), + }, + ), + ( + "minecraft:bubble_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:bubble_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:budding_amethyst", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(132, 96, 186), + }, + ), + ( + "minecraft:cactus", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(85, 127, 43), + }, + ), + ( + "minecraft:cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:calcite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 224, 220), + }, + ), + ( + "minecraft:campfire", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 88, 54), + }, + ), + ( + "minecraft:candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:carrots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(81, 124, 37), + }, + ), + ( + "minecraft:cartography_table", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 87, 67), + }, + ), + ( + "minecraft:carved_pumpkin", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(198, 118, 24), + }, + ), + ( + "minecraft:cauldron", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 72, 74), + }, + ), + ( + "minecraft:cave_air", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cave_vines", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(90, 109, 40), + }, + ), + ( + "minecraft:cave_vines_plant", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(88, 101, 38), + }, + ), + ( + "minecraft:chain", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:chain_command_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 161, 147), + }, + ), + ( + "minecraft:chest", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:chipped_anvil", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 72), + }, + ), + ( + "minecraft:chiseled_deepslate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 54, 54), + }, + ), + ( + "minecraft:chiseled_nether_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 23, 28), + }, + ), + ( + "minecraft:chiseled_polished_blackstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:chiseled_quartz_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(231, 226, 218), + }, + ), + ( + "minecraft:chiseled_red_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:chiseled_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:chiseled_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(119, 118, 119), + }, + ), + ( + "minecraft:chorus_flower", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(151, 120, 151), + }, + ), + ( + "minecraft:chorus_plant", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 57, 93), + }, + ), + ( + "minecraft:clay", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 166, 179), + }, + ), + ( + "minecraft:coal_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(16, 15, 15), + }, + ), + ( + "minecraft:coal_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(105, 105, 105), + }, + ), + ( + "minecraft:coarse_dirt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(119, 85, 59), + }, + ), + ( + "minecraft:cobbled_deepslate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 77, 80), + }, + ), + ( + "minecraft:cobbled_deepslate_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 77, 80), + }, + ), + ( + "minecraft:cobbled_deepslate_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 77, 80), + }, + ), + ( + "minecraft:cobbled_deepslate_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 77, 80), + }, + ), + ( + "minecraft:cobblestone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 127, 127), + }, + ), + ( + "minecraft:cobblestone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 127, 127), + }, + ), + ( + "minecraft:cobblestone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 127, 127), + }, + ), + ( + "minecraft:cobblestone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 127, 127), + }, + ), + ( + "minecraft:cobweb", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(228, 233, 234), + }, + ), + ( + "minecraft:cocoa", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(156, 94, 43), + }, + ), + ( + "minecraft:command_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 136, 108), + }, + ), + ( + "minecraft:comparator", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(166, 161, 159), + }, + ), + ( + "minecraft:composter", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(88, 61, 23), + }, + ), + ( + "minecraft:conduit", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(159, 139, 113), + }, + ), + ( + "minecraft:copper_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 107, 79), + }, + ), + ( + "minecraft:copper_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(124, 125, 120), + }, + ), + ( + "minecraft:cornflower", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cracked_deepslate_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(64, 64, 65), + }, + ), + ( + "minecraft:cracked_deepslate_tiles", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(52, 52, 52), + }, + ), + ( + "minecraft:cracked_nether_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(40, 20, 23), + }, + ), + ( + "minecraft:cracked_polished_blackstone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 37, 43), + }, + ), + ( + "minecraft:cracked_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(118, 117, 118), + }, + ), + ( + "minecraft:crafting_table", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(119, 73, 42), + }, + ), + ( + "minecraft:creeper_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:creeper_wall_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:crimson_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:crimson_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 54, 79), + }, + ), + ( + "minecraft:crimson_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_fungus", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:crimson_hyphae", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(92, 25, 29), + }, + ), + ( + "minecraft:crimson_nylium", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(130, 31, 31), + }, + ), + ( + "minecraft:crimson_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_roots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(126, 8, 41), + }, + ), + ( + "minecraft:crimson_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 48, 70), + }, + ), + ( + "minecraft:crimson_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(112, 49, 70), + }, + ), + ( + "minecraft:crimson_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 50, 72), + }, + ), + ( + "minecraft:crimson_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:crying_obsidian", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(32, 10, 60), + }, + ), + ( + "minecraft:cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:cut_red_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:cut_red_sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:cut_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:cut_sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:cyan_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cyan_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cyan_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cyan_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:cyan_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(21, 137, 145), + }, + ), + ( + "minecraft:cyan_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(21, 119, 136), + }, + ), + ( + "minecraft:cyan_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(36, 147, 157), + }, + ), + ( + "minecraft:cyan_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(52, 118, 125), + }, + ), + ( + "minecraft:cyan_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 121, 135), + }, + ), + ( + "minecraft:cyan_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(76, 127, 153), + }, + ), + ( + "minecraft:cyan_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 122, 147), + }, + ), + ( + "minecraft:cyan_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(86, 91, 91), + }, + ), + ( + "minecraft:cyan_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:cyan_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(21, 137, 145), + }, + ), + ( + "minecraft:damaged_anvil", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 72), + }, + ), + ( + "minecraft:dandelion", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dark_oak_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dark_oak_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(76, 51, 25), + }, + ), + ( + "minecraft:dark_oak_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + color: BlockColor(150, 150, 150), + }, + ), + ( + "minecraft:dark_oak_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(67, 45, 22), + }, + ), + ( + "minecraft:dark_oak_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(61, 90, 30), + }, + ), + ( + "minecraft:dark_oak_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 43, 20), + }, + ), + ( + "minecraft:dark_oak_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(75, 49, 23), + }, + ), + ( + "minecraft:dark_oak_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dark_oak_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(60, 46, 26), + }, + ), + ( + "minecraft:dark_prismarine", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(51, 91, 75), + }, + ), + ( + "minecraft:dark_prismarine_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(51, 91, 75), + }, + ), + ( + "minecraft:dark_prismarine_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(51, 91, 75), + }, + ), + ( + "minecraft:daylight_detector", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(130, 116, 94), + }, + ), + ( + "minecraft:dead_brain_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_brain_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(124, 117, 114), + }, + ), + ( + "minecraft:dead_brain_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_brain_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_bubble_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_bubble_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 123, 119), + }, + ), + ( + "minecraft:dead_bubble_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_bubble_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(107, 78, 40), + }, + ), + ( + "minecraft:dead_fire_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_fire_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 123, 119), + }, + ), + ( + "minecraft:dead_fire_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_fire_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_horn_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_horn_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(133, 126, 122), + }, + ), + ( + "minecraft:dead_horn_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_horn_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_tube_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_tube_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(130, 123, 119), + }, + ), + ( + "minecraft:dead_tube_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dead_tube_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:deepslate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 80, 82), + }, + ), + ( + "minecraft:deepslate_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(70, 70, 71), + }, + ), + ( + "minecraft:deepslate_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(70, 70, 71), + }, + ), + ( + "minecraft:deepslate_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(70, 70, 71), + }, + ), + ( + "minecraft:deepslate_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(70, 70, 71), + }, + ), + ( + "minecraft:deepslate_coal_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(74, 74, 76), + }, + ), + ( + "minecraft:deepslate_copper_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(92, 93, 89), + }, + ), + ( + "minecraft:deepslate_diamond_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(83, 106, 106), + }, + ), + ( + "minecraft:deepslate_emerald_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(78, 104, 87), + }, + ), + ( + "minecraft:deepslate_gold_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 102, 78), + }, + ), + ( + "minecraft:deepslate_iron_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(106, 99, 94), + }, + ), + ( + "minecraft:deepslate_lapis_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 90, 115), + }, + ), + ( + "minecraft:deepslate_redstone_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(104, 73, 74), + }, + ), + ( + "minecraft:deepslate_tile_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 54, 55), + }, + ), + ( + "minecraft:deepslate_tile_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 54, 55), + }, + ), + ( + "minecraft:deepslate_tile_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 54, 55), + }, + ), + ( + "minecraft:deepslate_tiles", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 54, 55), + }, + ), + ( + "minecraft:detector_rail", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(123, 104, 90), + }, + ), + ( + "minecraft:diamond_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(98, 237, 228), + }, + ), + ( + "minecraft:diamond_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(121, 141, 140), + }, + ), + ( + "minecraft:diorite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(188, 188, 188), + }, + ), + ( + "minecraft:diorite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(188, 188, 188), + }, + ), + ( + "minecraft:diorite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(188, 188, 188), + }, + ), + ( + "minecraft:diorite_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(188, 188, 188), + }, + ), + ( + "minecraft:dirt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(134, 96, 67), + }, + ), + ( + "minecraft:dirt_path", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(148, 121, 65), + }, + ), + ( + "minecraft:dispenser", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 109, 109), + }, + ), + ( + "minecraft:dragon_egg", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(12, 9, 15), + }, + ), + ( + "minecraft:dragon_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dragon_wall_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:dried_kelp_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(50, 58, 38), + }, + ), + ( + "minecraft:dripstone_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(134, 107, 92), + }, + ), + ( + "minecraft:dropper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 109, 109), + }, + ), + ( + "minecraft:emerald_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(42, 203, 87), + }, + ), + ( + "minecraft:emerald_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(108, 136, 115), + }, + ), + ( + "minecraft:enchanting_table", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(128, 75, 85), + }, + ), + ( + "minecraft:end_gateway", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(15, 10, 24), + }, + ), + ( + "minecraft:end_portal", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(15, 10, 24), + }, + ), + ( + "minecraft:end_portal_frame", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(91, 120, 97), + }, + ), + ( + "minecraft:end_rod", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:end_stone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(219, 222, 158), + }, + ), + ( + "minecraft:end_stone_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(218, 224, 162), + }, + ), + ( + "minecraft:end_stone_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(218, 224, 162), + }, + ), + ( + "minecraft:end_stone_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(218, 224, 162), + }, + ), + ( + "minecraft:end_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(218, 224, 162), + }, + ), + ( + "minecraft:ender_chest", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(15, 10, 24), + }, + ), + ( + "minecraft:exposed_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(161, 125, 103), + }, + ), + ( + "minecraft:exposed_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:exposed_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:exposed_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:farmland", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(81, 44, 15), + }, + ), + ( + "minecraft:fern", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:fire", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(211, 140, 53), + }, + ), + ( + "minecraft:fire_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:fire_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(163, 35, 46), + }, + ), + ( + "minecraft:fire_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:fire_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:fletching_table", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(197, 180, 133), + }, + ), + ( + "minecraft:flower_pot", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(124, 68, 53), + }, + ), + ( + "minecraft:flowering_azalea", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(112, 121, 64), + }, + ), + ( + "minecraft:flowering_azalea_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 111, 60), + }, + ), + ( + "minecraft:frosted_ice", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(140, 181, 252), + }, + ), + ( + "minecraft:furnace", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 109, 109), + }, + ), + ( + "minecraft:gilded_blackstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(55, 42, 38), + }, + ), + ( + "minecraft:glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(175, 213, 219), + }, + ), + ( + "minecraft:glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(170, 210, 217), + }, + ), + ( + "minecraft:glow_item_frame", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:glow_lichen", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:glowstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(171, 131, 84), + }, + ), + ( + "minecraft:gold_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(246, 208, 61), + }, + ), + ( + "minecraft:gold_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(145, 133, 106), + }, + ), + ( + "minecraft:granite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 103, 85), + }, + ), + ( + "minecraft:granite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 103, 85), + }, + ), + ( + "minecraft:granite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 103, 85), + }, + ), + ( + "minecraft:granite_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 103, 85), + }, + ), + ( + "minecraft:grass", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:grass_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(147, 147, 147), + }, + ), + ( + "minecraft:grass_path", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(148, 121, 65), + }, + ), + ( + "minecraft:gravel", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 127, 126), + }, + ), + ( + "minecraft:gray_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:gray_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:gray_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:gray_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:gray_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(62, 68, 71), + }, + ), + ( + "minecraft:gray_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(54, 57, 61), + }, + ), + ( + "minecraft:gray_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(76, 81, 84), + }, + ), + ( + "minecraft:gray_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(83, 90, 93), + }, + ), + ( + "minecraft:gray_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(55, 58, 62), + }, + ), + ( + "minecraft:gray_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(76, 76, 76), + }, + ), + ( + "minecraft:gray_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 73, 73), + }, + ), + ( + "minecraft:gray_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(57, 42, 35), + }, + ), + ( + "minecraft:gray_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:gray_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(62, 68, 71), + }, + ), + ( + "minecraft:green_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:green_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:green_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:green_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:green_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(84, 109, 27), + }, + ), + ( + "minecraft:green_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 91, 36), + }, + ), + ( + "minecraft:green_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(97, 119, 44), + }, + ), + ( + "minecraft:green_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(117, 142, 67), + }, + ), + ( + "minecraft:green_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 100, 31), + }, + ), + ( + "minecraft:green_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(102, 127, 51), + }, + ), + ( + "minecraft:green_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(97, 122, 48), + }, + ), + ( + "minecraft:green_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(76, 83, 42), + }, + ), + ( + "minecraft:green_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:green_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(84, 109, 27), + }, + ), + ( + "minecraft:grindstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 142, 142), + }, + ), + ( + "minecraft:hanging_roots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(161, 115, 91), + }, + ), + ( + "minecraft:hay_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(165, 139, 12), + }, + ), + ( + "minecraft:heavy_weighted_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(220, 220, 220), + }, + ), + ( + "minecraft:honey_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(251, 185, 52), + }, + ), + ( + "minecraft:honeycomb_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(229, 148, 29), + }, + ), + ( + "minecraft:hopper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(75, 74, 75), + }, + ), + ( + "minecraft:horn_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:horn_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(216, 199, 66), + }, + ), + ( + "minecraft:horn_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:horn_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:ice", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(145, 183, 253), + }, + ), + ( + "minecraft:infested_chiseled_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(119, 118, 119), + }, + ), + ( + "minecraft:infested_cobblestone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 127, 127), + }, + ), + ( + "minecraft:infested_cracked_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(118, 117, 118), + }, + ), + ( + "minecraft:infested_deepslate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 80, 82), + }, + ), + ( + "minecraft:infested_mossy_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 121, 105), + }, + ), + ( + "minecraft:infested_stone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:infested_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 121, 122), + }, + ), + ( + "minecraft:iron_bars", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 139, 135), + }, + ), + ( + "minecraft:iron_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(220, 220, 220), + }, + ), + ( + "minecraft:iron_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(194, 193, 193), + }, + ), + ( + "minecraft:iron_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(136, 129, 122), + }, + ), + ( + "minecraft:iron_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(202, 202, 202), + }, + ), + ( + "minecraft:item_frame", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:jack_o_lantern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(214, 152, 52), + }, + ), + ( + "minecraft:jigsaw", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 69, 81), + }, + ), + ( + "minecraft:jukebox", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 64, 47), + }, + ), + ( + "minecraft:jungle_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:jungle_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(163, 119, 84), + }, + ), + ( + "minecraft:jungle_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + color: BlockColor(156, 154, 143), + }, + ), + ( + "minecraft:jungle_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 109, 70), + }, + ), + ( + "minecraft:jungle_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 81, 16), + }, + ), + ( + "minecraft:jungle_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 115, 80), + }, + ), + ( + "minecraft:jungle_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(152, 110, 77), + }, + ), + ( + "minecraft:jungle_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:jungle_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(85, 67, 25), + }, + ), + ( + "minecraft:kelp", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:kelp_plant", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(86, 130, 42), + }, + ), + ( + "minecraft:ladder", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lantern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(106, 91, 83), + }, + ), + ( + "minecraft:lapis_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(30, 67, 140), + }, + ), + ( + "minecraft:lapis_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(107, 117, 141), + }, + ), + ( + "minecraft:large_amethyst_bud", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:large_fern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:lava", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(212, 90, 18), + }, + ), + ( + "minecraft:lava_cauldron", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 72, 74), + }, + ), + ( + "minecraft:lectern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(173, 137, 83), + }, + ), + ( + "minecraft:lever", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_blue_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_blue_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_blue_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_blue_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:light_blue_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(58, 175, 217), + }, + ), + ( + "minecraft:light_blue_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(35, 137, 198), + }, + ), + ( + "minecraft:light_blue_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(74, 180, 213), + }, + ), + ( + "minecraft:light_blue_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(94, 164, 208), + }, + ), + ( + "minecraft:light_blue_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(49, 163, 212), + }, + ), + ( + "minecraft:light_blue_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(102, 153, 216), + }, + ), + ( + "minecraft:light_blue_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(97, 147, 208), + }, + ), + ( + "minecraft:light_blue_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(113, 108, 137), + }, + ), + ( + "minecraft:light_blue_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_blue_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(58, 175, 217), + }, + ), + ( + "minecraft:light_gray_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_gray_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_gray_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_gray_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:light_gray_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 142, 134), + }, + ), + ( + "minecraft:light_gray_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 115), + }, + ), + ( + "minecraft:light_gray_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 154, 148), + }, + ), + ( + "minecraft:light_gray_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(144, 166, 167), + }, + ), + ( + "minecraft:light_gray_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(124, 124, 115), + }, + ), + ( + "minecraft:light_gray_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(153, 153, 153), + }, + ), + ( + "minecraft:light_gray_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(147, 147, 147), + }, + ), + ( + "minecraft:light_gray_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(135, 106, 97), + }, + ), + ( + "minecraft:light_gray_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:light_gray_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 142, 134), + }, + ), + ( + "minecraft:light_weighted_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(246, 208, 61), + }, + ), + ( + "minecraft:lightning_rod", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lilac", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 125, 147), + }, + ), + ( + "minecraft:lily_of_the_valley", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lily_pad", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(133, 133, 133), + }, + ), + ( + "minecraft:lime_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lime_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lime_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lime_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:lime_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(112, 185, 25), + }, + ), + ( + "minecraft:lime_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(94, 168, 24), + }, + ), + ( + "minecraft:lime_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 189, 41), + }, + ), + ( + "minecraft:lime_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 197, 55), + }, + ), + ( + "minecraft:lime_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 172, 23), + }, + ), + ( + "minecraft:lime_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 204, 25), + }, + ), + ( + "minecraft:lime_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 196, 24), + }, + ), + ( + "minecraft:lime_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 117, 52), + }, + ), + ( + "minecraft:lime_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:lime_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(112, 185, 25), + }, + ), + ( + "minecraft:lodestone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(147, 149, 152), + }, + ), + ( + "minecraft:loom", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 119, 91), + }, + ), + ( + "minecraft:magenta_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:magenta_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:magenta_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:magenta_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:magenta_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(189, 68, 179), + }, + ), + ( + "minecraft:magenta_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(169, 48, 159), + }, + ), + ( + "minecraft:magenta_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 83, 184), + }, + ), + ( + "minecraft:magenta_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(208, 100, 191), + }, + ), + ( + "minecraft:magenta_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(173, 54, 163), + }, + ), + ( + "minecraft:magenta_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(178, 76, 216), + }, + ), + ( + "minecraft:magenta_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(171, 73, 208), + }, + ), + ( + "minecraft:magenta_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(149, 88, 108), + }, + ), + ( + "minecraft:magenta_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:magenta_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(189, 68, 179), + }, + ), + ( + "minecraft:magma_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 63, 31), + }, + ), + ( + "minecraft:medium_amethyst_bud", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:melon", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(111, 144, 30), + }, + ), + ( + "minecraft:melon_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(153, 153, 153), + }, + ), + ( + "minecraft:moss_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(89, 109, 45), + }, + ), + ( + "minecraft:moss_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(89, 109, 45), + }, + ), + ( + "minecraft:mossy_cobblestone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 118, 94), + }, + ), + ( + "minecraft:mossy_cobblestone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 118, 94), + }, + ), + ( + "minecraft:mossy_cobblestone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 118, 94), + }, + ), + ( + "minecraft:mossy_cobblestone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 118, 94), + }, + ), + ( + "minecraft:mossy_stone_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 121, 105), + }, + ), + ( + "minecraft:mossy_stone_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 121, 105), + }, + ), + ( + "minecraft:mossy_stone_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 121, 105), + }, + ), + ( + "minecraft:mossy_stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 121, 105), + }, + ), + ( + "minecraft:moving_piston", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:mushroom_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(203, 196, 185), + }, + ), + ( + "minecraft:mycelium", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(111, 98, 101), + }, + ), + ( + "minecraft:nether_brick_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 21, 26), + }, + ), + ( + "minecraft:nether_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 21, 26), + }, + ), + ( + "minecraft:nether_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 21, 26), + }, + ), + ( + "minecraft:nether_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 21, 26), + }, + ), + ( + "minecraft:nether_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 21, 26), + }, + ), + ( + "minecraft:nether_gold_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 54, 42), + }, + ), + ( + "minecraft:nether_portal", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(89, 11, 192), + }, + ), + ( + "minecraft:nether_quartz_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(117, 65, 62), + }, + ), + ( + "minecraft:nether_sprouts", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(19, 151, 133), + }, + ), + ( + "minecraft:nether_wart", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(111, 18, 19), + }, + ), + ( + "minecraft:nether_wart_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 2, 2), + }, + ), + ( + "minecraft:netherite_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(66, 61, 63), + }, + ), + ( + "minecraft:netherrack", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(97, 38, 38), + }, + ), + ( + "minecraft:note_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(88, 58, 40), + }, + ), + ( + "minecraft:oak_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:oak_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(140, 110, 66), + }, + ), + ( + "minecraft:oak_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + color: BlockColor(144, 144, 144), + }, + ), + ( + "minecraft:oak_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(151, 121, 73), + }, + ), + ( + "minecraft:oak_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 106, 40), + }, + ), + ( + "minecraft:oak_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:oak_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(124, 99, 56), + }, + ), + ( + "minecraft:oak_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:oak_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 85, 50), + }, + ), + ( + "minecraft:observer", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(98, 98, 98), + }, + ), + ( + "minecraft:obsidian", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(15, 10, 24), + }, + ), + ( + "minecraft:orange_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:orange_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:orange_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:orange_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:orange_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(240, 118, 19), + }, + ), + ( + "minecraft:orange_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(224, 97, 0), + }, + ), + ( + "minecraft:orange_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(227, 131, 31), + }, + ), + ( + "minecraft:orange_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 147, 91), + }, + ), + ( + "minecraft:orange_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(234, 106, 8), + }, + ), + ( + "minecraft:orange_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(216, 127, 51), + }, + ), + ( + "minecraft:orange_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(208, 122, 48), + }, + ), + ( + "minecraft:orange_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(161, 83, 37), + }, + ), + ( + "minecraft:orange_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:orange_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:orange_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(240, 118, 19), + }, + ), + ( + "minecraft:oxeye_daisy", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:oxidized_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(82, 162, 132), + }, + ), + ( + "minecraft:oxidized_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:oxidized_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:oxidized_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:packed_ice", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(141, 180, 250), + }, + ), + ( + "minecraft:peony", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(129, 126, 139), + }, + ), + ( + "minecraft:petrified_oak_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:pink_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:pink_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:pink_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:pink_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:pink_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(237, 141, 172), + }, + ), + ( + "minecraft:pink_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(213, 101, 142), + }, + ), + ( + "minecraft:pink_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(228, 153, 181), + }, + ), + ( + "minecraft:pink_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 154, 181), + }, + ), + ( + "minecraft:pink_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(230, 121, 157), + }, + ), + ( + "minecraft:pink_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(242, 127, 165), + }, + ), + ( + "minecraft:pink_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(233, 122, 159), + }, + ), + ( + "minecraft:pink_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(161, 78, 78), + }, + ), + ( + "minecraft:pink_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:pink_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:pink_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(237, 141, 172), + }, + ), + ( + "minecraft:piston", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 104, 96), + }, + ), + ( + "minecraft:piston_head", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 127, 87), + }, + ), + ( + "minecraft:player_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:player_wall_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:podzol", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(91, 63, 24), + }, + ), + ( + "minecraft:pointed_dripstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(129, 102, 89), + }, + ), + ( + "minecraft:polished_andesite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(132, 134, 133), + }, + ), + ( + "minecraft:polished_andesite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(132, 134, 133), + }, + ), + ( + "minecraft:polished_andesite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(132, 134, 133), + }, + ), + ( + "minecraft:polished_basalt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 98, 100), + }, + ), + ( + "minecraft:polished_blackstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:polished_blackstone_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(48, 42, 49), + }, + ), + ( + "minecraft:polished_blackstone_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(48, 42, 49), + }, + ), + ( + "minecraft:polished_blackstone_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(48, 42, 49), + }, + ), + ( + "minecraft:polished_blackstone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(48, 42, 49), + }, + ), + ( + "minecraft:polished_blackstone_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:polished_blackstone_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:polished_blackstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:polished_blackstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:polished_blackstone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 48, 56), + }, + ), + ( + "minecraft:polished_deepslate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 73), + }, + ), + ( + "minecraft:polished_deepslate_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 73), + }, + ), + ( + "minecraft:polished_deepslate_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 73), + }, + ), + ( + "minecraft:polished_deepslate_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 73), + }, + ), + ( + "minecraft:polished_diorite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 193, 194), + }, + ), + ( + "minecraft:polished_diorite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 193, 194), + }, + ), + ( + "minecraft:polished_diorite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 193, 194), + }, + ), + ( + "minecraft:polished_granite", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 106, 89), + }, + ), + ( + "minecraft:polished_granite_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 106, 89), + }, + ), + ( + "minecraft:polished_granite_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 106, 89), + }, + ), + ( + "minecraft:poppy", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:potatoes", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(84, 135, 47), + }, + ), + ( + "minecraft:potted_acacia_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(118, 117, 23), + }, + ), + ( + "minecraft:potted_allium", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(158, 137, 183), + }, + ), + ( + "minecraft:potted_azalea_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(101, 124, 47), + }, + ), + ( + "minecraft:potted_azure_bluet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(169, 204, 127), + }, + ), + ( + "minecraft:potted_bamboo", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 144, 19), + }, + ), + ( + "minecraft:potted_birch_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 160, 79), + }, + ), + ( + "minecraft:potted_blue_orchid", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 162, 168), + }, + ), + ( + "minecraft:potted_brown_mushroom", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(153, 116, 92), + }, + ), + ( + "minecraft:potted_cactus", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(85, 127, 43), + }, + ), + ( + "minecraft:potted_cornflower", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 121, 146), + }, + ), + ( + "minecraft:potted_crimson_fungus", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(141, 44, 29), + }, + ), + ( + "minecraft:potted_crimson_roots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 8, 41), + }, + ), + ( + "minecraft:potted_dandelion", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(147, 172, 43), + }, + ), + ( + "minecraft:potted_dark_oak_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(61, 90, 30), + }, + ), + ( + "minecraft:potted_dead_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(107, 78, 40), + }, + ), + ( + "minecraft:potted_fern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(124, 124, 124), + }, + ), + ( + "minecraft:potted_flowering_azalea_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(112, 121, 64), + }, + ), + ( + "minecraft:potted_jungle_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 81, 16), + }, + ), + ( + "minecraft:potted_lily_of_the_valley", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(123, 174, 95), + }, + ), + ( + "minecraft:potted_oak_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(77, 106, 40), + }, + ), + ( + "minecraft:potted_orange_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 142, 30), + }, + ), + ( + "minecraft:potted_oxeye_daisy", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(179, 202, 143), + }, + ), + ( + "minecraft:potted_pink_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 157, 78), + }, + ), + ( + "minecraft:potted_poppy", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(128, 64, 37), + }, + ), + ( + "minecraft:potted_red_mushroom", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(216, 75, 67), + }, + ), + ( + "minecraft:potted_red_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(89, 128, 32), + }, + ), + ( + "minecraft:potted_spruce_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 60, 36), + }, + ), + ( + "minecraft:potted_warped_fungus", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(74, 109, 87), + }, + ), + ( + "minecraft:potted_warped_roots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 136, 123), + }, + ), + ( + "minecraft:potted_white_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(93, 164, 71), + }, + ), + ( + "minecraft:potted_wither_rose", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(41, 44, 23), + }, + ), + ( + "minecraft:powder_snow", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 253, 253), + }, + ), + ( + "minecraft:powder_snow_cauldron", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 72, 74), + }, + ), + ( + "minecraft:powered_rail", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(137, 109, 74), + }, + ), + ( + "minecraft:prismarine", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 156, 151), + }, + ), + ( + "minecraft:prismarine_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 171, 158), + }, + ), + ( + "minecraft:prismarine_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 171, 158), + }, + ), + ( + "minecraft:prismarine_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 171, 158), + }, + ), + ( + "minecraft:prismarine_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 156, 151), + }, + ), + ( + "minecraft:prismarine_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 156, 151), + }, + ), + ( + "minecraft:prismarine_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(99, 156, 151), + }, + ), + ( + "minecraft:pumpkin", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(198, 118, 24), + }, + ), + ( + "minecraft:pumpkin_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(154, 154, 154), + }, + ), + ( + "minecraft:purple_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:purple_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:purple_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:purple_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:purple_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(121, 42, 172), + }, + ), + ( + "minecraft:purple_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(100, 31, 156), + }, + ), + ( + "minecraft:purple_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 55, 177), + }, + ), + ( + "minecraft:purple_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 48, 152), + }, + ), + ( + "minecraft:purple_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 32, 156), + }, + ), + ( + "minecraft:purple_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(127, 63, 178), + }, + ), + ( + "minecraft:purple_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 61, 171), + }, + ), + ( + "minecraft:purple_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(118, 70, 86), + }, + ), + ( + "minecraft:purple_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:purple_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(121, 42, 172), + }, + ), + ( + "minecraft:purpur_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(169, 125, 169), + }, + ), + ( + "minecraft:purpur_pillar", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(171, 129, 171), + }, + ), + ( + "minecraft:purpur_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(169, 125, 169), + }, + ), + ( + "minecraft:purpur_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(169, 125, 169), + }, + ), + ( + "minecraft:quartz_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:quartz_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(234, 229, 221), + }, + ), + ( + "minecraft:quartz_pillar", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 230, 224), + }, + ), + ( + "minecraft:quartz_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:quartz_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:rail", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 111, 88), + }, + ), + ( + "minecraft:raw_copper_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 105, 79), + }, + ), + ( + "minecraft:raw_gold_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(221, 169, 46), + }, + ), + ( + "minecraft:raw_iron_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(166, 135, 107), + }, + ), + ( + "minecraft:red_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:red_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 39, 34), + }, + ), + ( + "minecraft:red_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 32, 32), + }, + ), + ( + "minecraft:red_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(168, 54, 50), + }, + ), + ( + "minecraft:red_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 59, 53), + }, + ), + ( + "minecraft:red_mushroom", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_mushroom_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(200, 46, 45), + }, + ), + ( + "minecraft:red_nether_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(69, 7, 9), + }, + ), + ( + "minecraft:red_nether_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(69, 7, 9), + }, + ), + ( + "minecraft:red_nether_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(69, 7, 9), + }, + ), + ( + "minecraft:red_nether_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(69, 7, 9), + }, + ), + ( + "minecraft:red_sand", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(190, 102, 33), + }, + ), + ( + "minecraft:red_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:red_sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:red_sandstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:red_sandstone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:red_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(140, 31, 30), + }, + ), + ( + "minecraft:red_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(153, 51, 51), + }, + ), + ( + "minecraft:red_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(147, 48, 48), + }, + ), + ( + "minecraft:red_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(143, 61, 46), + }, + ), + ( + "minecraft:red_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:red_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 39, 34), + }, + ), + ( + "minecraft:redstone_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(175, 24, 5), + }, + ), + ( + "minecraft:redstone_lamp", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(95, 54, 30), + }, + ), + ( + "minecraft:redstone_ore", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(140, 109, 109), + }, + ), + ( + "minecraft:redstone_torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:redstone_wall_torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:redstone_wire", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(175, 24, 5), + }, + ), + ( + "minecraft:repeater", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 157, 156), + }, + ), + ( + "minecraft:repeating_command_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(129, 111, 176), + }, + ), + ( + "minecraft:respawn_anchor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(75, 26, 144), + }, + ), + ( + "minecraft:rooted_dirt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(144, 103, 76), + }, + ), + ( + "minecraft:rose_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(131, 66, 37), + }, + ), + ( + "minecraft:sand", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(219, 207, 163), + }, + ), + ( + "minecraft:sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:sandstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:sandstone_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:scaffolding", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(174, 134, 80), + }, + ), + ( + "minecraft:sculk_sensor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(7, 70, 84), + }, + ), + ( + "minecraft:sea_lantern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(172, 199, 190), + }, + ), + ( + "minecraft:sea_pickle", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(90, 97, 39), + }, + ), + ( + "minecraft:seagrass", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:shroomlight", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(240, 146, 70), + }, + ), + ( + "minecraft:shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(139, 96, 139), + }, + ), + ( + "minecraft:sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:skeleton_skull", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:skeleton_wall_skull", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:slime_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(111, 192, 91), + }, + ), + ( + "minecraft:small_amethyst_bud", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:small_dripleaf", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:smithing_table", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(57, 58, 70), + }, + ), + ( + "minecraft:smoker", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(85, 83, 81), + }, + ), + ( + "minecraft:smooth_basalt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 72, 78), + }, + ), + ( + "minecraft:smooth_quartz", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:smooth_quartz_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:smooth_quartz_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(235, 229, 222), + }, + ), + ( + "minecraft:smooth_red_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:smooth_red_sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:smooth_red_sandstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(181, 97, 31), + }, + ), + ( + "minecraft:smooth_sandstone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:smooth_sandstone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:smooth_sandstone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(223, 214, 170), + }, + ), + ( + "minecraft:smooth_stone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(158, 158, 158), + }, + ), + ( + "minecraft:smooth_stone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(158, 158, 158), + }, + ), + ( + "minecraft:snow", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(249, 254, 254), + }, + ), + ( + "minecraft:snow_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(249, 254, 254), + }, + ), + ( + "minecraft:soul_campfire", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(80, 204, 208), + }, + ), + ( + "minecraft:soul_fire", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(51, 192, 197), + }, + ), + ( + "minecraft:soul_lantern", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(71, 99, 114), + }, + ), + ( + "minecraft:soul_sand", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(81, 62, 50), + }, + ), + ( + "minecraft:soul_soil", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(75, 57, 46), + }, + ), + ( + "minecraft:soul_torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:soul_wall_torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:spawner", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(36, 46, 62), + }, + ), + ( + "minecraft:sponge", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(195, 192, 74), + }, + ), + ( + "minecraft:spore_blossom", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(206, 96, 158), + }, + ), + ( + "minecraft:spruce_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:spruce_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(106, 80, 48), + }, + ), + ( + "minecraft:spruce_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_leaves", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Spruce}), + color: BlockColor(126, 126, 126), + }, + ), + ( + "minecraft:spruce_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(108, 80, 46), + }, + ), + ( + "minecraft:spruce_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_sapling", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 60, 36), + }, + ), + ( + "minecraft:spruce_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(114, 84, 48), + }, + ), + ( + "minecraft:spruce_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(103, 79, 47), + }, + ), + ( + "minecraft:spruce_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:spruce_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(58, 37, 16), + }, + ), + ( + "minecraft:sticky_piston", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(110, 104, 96), + }, + ), + ( + "minecraft:stone", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:stone_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 121, 122), + }, + ), + ( + "minecraft:stone_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 121, 122), + }, + ), + ( + "minecraft:stone_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 121, 122), + }, + ), + ( + "minecraft:stone_bricks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(122, 121, 122), + }, + ), + ( + "minecraft:stone_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:stone_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:stone_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:stone_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(125, 125, 125), + }, + ), + ( + "minecraft:stonecutter", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(123, 118, 111), + }, + ), + ( + "minecraft:stripped_acacia_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(166, 91, 51), + }, + ), + ( + "minecraft:stripped_acacia_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(174, 92, 59), + }, + ), + ( + "minecraft:stripped_birch_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 171, 116), + }, + ), + ( + "minecraft:stripped_birch_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(196, 176, 118), + }, + ), + ( + "minecraft:stripped_crimson_hyphae", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(137, 57, 90), + }, + ), + ( + "minecraft:stripped_crimson_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(121, 56, 82), + }, + ), + ( + "minecraft:stripped_dark_oak_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(65, 44, 22), + }, + ), + ( + "minecraft:stripped_dark_oak_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(72, 56, 36), + }, + ), + ( + "minecraft:stripped_jungle_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(165, 122, 81), + }, + ), + ( + "minecraft:stripped_jungle_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(171, 132, 84), + }, + ), + ( + "minecraft:stripped_oak_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(160, 129, 77), + }, + ), + ( + "minecraft:stripped_oak_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(177, 144, 86), + }, + ), + ( + "minecraft:stripped_spruce_log", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(105, 80, 46), + }, + ), + ( + "minecraft:stripped_spruce_wood", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(115, 89, 52), + }, + ), + ( + "minecraft:stripped_warped_hyphae", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(57, 150, 147), + }, + ), + ( + "minecraft:stripped_warped_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(52, 128, 124), + }, + ), + ( + "minecraft:structure_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(88, 74, 90), + }, + ), + ( + "minecraft:structure_void", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:sugar_cane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(148, 192, 101), + }, + ), + ( + "minecraft:sunflower", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(246, 196, 54), + }, + ), + ( + "minecraft:sweet_berry_bush", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(68, 77, 50), + }, + ), + ( + "minecraft:tall_grass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(151, 149, 151), + }, + ), + ( + "minecraft:tall_seagrass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(59, 139, 14), + }, + ), + ( + "minecraft:target", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(226, 170, 157), + }, + ), + ( + "minecraft:terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(152, 94, 67), + }, + ), + ( + "minecraft:tinted_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 38, 46), + }, + ), + ( + "minecraft:tnt", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(142, 62, 53), + }, + ), + ( + "minecraft:torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:trapped_chest", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(162, 130, 78), + }, + ), + ( + "minecraft:tripwire", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:tripwire_hook", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:tube_coral", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:tube_coral_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(49, 87, 206), + }, + ), + ( + "minecraft:tube_coral_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:tube_coral_wall_fan", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:tuff", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(108, 109, 102), + }, + ), + ( + "minecraft:turtle_egg", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(228, 226, 191), + }, + ), + ( + "minecraft:twisting_vines", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 143, 124), + }, + ), + ( + "minecraft:twisting_vines_plant", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 135, 122), + }, + ), + ( + "minecraft:vine", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + color: BlockColor(116, 116, 116), + }, + ), + ( + "minecraft:void_air", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:wall_torch", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:warped_button", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:warped_door", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(44, 126, 120), + }, + ), + ( + "minecraft:warped_fence", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_fungus", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:warped_hyphae", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(58, 58, 77), + }, + ), + ( + "minecraft:warped_nylium", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 114, 101), + }, + ), + ( + "minecraft:warped_planks", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_roots", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(20, 138, 124), + }, + ), + ( + "minecraft:warped_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(43, 104, 99), + }, + ), + ( + "minecraft:warped_stem", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(53, 109, 110), + }, + ), + ( + "minecraft:warped_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(47, 119, 111), + }, + ), + ( + "minecraft:warped_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:warped_wart_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(22, 119, 121), + }, + ), + ( + "minecraft:water", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque|Water}), + color: BlockColor(177, 177, 177), + }, + ), + ( + "minecraft:water_cauldron", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(73, 72, 74), + }, + ), + ( + "minecraft:waxed_copper_block", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(192, 107, 79), + }, + ), + ( + "minecraft:waxed_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:waxed_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:waxed_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(191, 106, 80), + }, + ), + ( + "minecraft:waxed_exposed_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(161, 125, 103), + }, + ), + ( + "minecraft:waxed_exposed_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:waxed_exposed_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:waxed_exposed_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(154, 121, 101), + }, + ), + ( + "minecraft:waxed_oxidized_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(82, 162, 132), + }, + ), + ( + "minecraft:waxed_oxidized_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:waxed_oxidized_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:waxed_oxidized_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(79, 153, 126), + }, + ), + ( + "minecraft:waxed_weathered_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(108, 153, 110), + }, + ), + ( + "minecraft:waxed_weathered_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:waxed_weathered_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:waxed_weathered_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:weathered_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(108, 153, 110), + }, + ), + ( + "minecraft:weathered_cut_copper", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:weathered_cut_copper_slab", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:weathered_cut_copper_stairs", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(109, 145, 107), + }, + ), + ( + "minecraft:weeping_vines", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(104, 1, 0), + }, + ), + ( + "minecraft:weeping_vines_plant", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(132, 16, 12), + }, + ), + ( + "minecraft:wet_sponge", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(171, 181, 70), + }, + ), + ( + "minecraft:wheat", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(166, 151, 73), + }, + ), + ( + "minecraft:white_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:white_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:white_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:white_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:white_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(233, 236, 236), + }, + ), + ( + "minecraft:white_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(207, 213, 214), + }, + ), + ( + "minecraft:white_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(225, 227, 227), + }, + ), + ( + "minecraft:white_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(188, 212, 202), + }, + ), + ( + "minecraft:white_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(215, 220, 221), + }, + ), + ( + "minecraft:white_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(255, 255, 255), + }, + ), + ( + "minecraft:white_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(246, 246, 246), + }, + ), + ( + "minecraft:white_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(209, 178, 161), + }, + ), + ( + "minecraft:white_tulip", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:white_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:white_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(233, 236, 236), + }, + ), + ( + "minecraft:wither_rose", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:wither_skeleton_skull", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:wither_skeleton_wall_skull", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:yellow_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:yellow_bed", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:yellow_candle", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:yellow_candle_cake", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 222, 214), + }, + ), + ( + "minecraft:yellow_carpet", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 197, 39), + }, + ), + ( + "minecraft:yellow_concrete", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(240, 175, 21), + }, + ), + ( + "minecraft:yellow_concrete_powder", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(232, 199, 54), + }, + ), + ( + "minecraft:yellow_glazed_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(234, 192, 88), + }, + ), + ( + "minecraft:yellow_shulker_box", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 188, 29), + }, + ), + ( + "minecraft:yellow_stained_glass", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(229, 229, 51), + }, + ), + ( + "minecraft:yellow_stained_glass_pane", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(221, 221, 48), + }, + ), + ( + "minecraft:yellow_terracotta", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(186, 133, 35), + }, + ), + ( + "minecraft:yellow_wall_banner", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:yellow_wool", + BlockType { + flags: make_bitflags!(BlockFlags::{Opaque}), + color: BlockColor(248, 197, 39), + }, + ), + ( + "minecraft:zombie_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:zombie_wall_head", + BlockType { + flags: make_bitflags!(BlockFlags::{}), + color: BlockColor(0, 0, 0), + }, + ), +]; diff --git a/src/resource/mod.rs b/src/resource/mod.rs new file mode 100644 index 0000000..cadac86 --- /dev/null +++ b/src/resource/mod.rs @@ -0,0 +1,33 @@ +mod block_types; + +use std::collections::HashMap; + +use enumflags2::{bitflags, BitFlags}; + +#[bitflags] +#[repr(u8)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum BlockFlags { + Opaque, + Grass, + Foliage, + Birch, + Spruce, + Water, +} + +#[derive(Debug, Clone, Copy)] +pub struct BlockColor(pub u8, pub u8, pub u8); + +#[derive(Debug, Clone, Copy)] +pub struct BlockType { + pub flags: BitFlags, + pub color: BlockColor, +} + +pub fn get_block_types() -> HashMap { + block_types::BLOCK_TYPES + .iter() + .map(|(k, v)| (String::from(*k), *v)) + .collect() +} From a174d627cdb76ca0d8508760375cb4c5036404d7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 10:22:38 +0100 Subject: [PATCH 063/460] Cargo.toml: change license to MIT The copy of the license text in the repository is dropped. --- Cargo.toml | 2 +- LICENSE | 22 ---------------------- 2 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 LICENSE diff --git a/Cargo.toml b/Cargo.toml index 1b43110..4c6ee7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "minedmap" version = "0.1.0" edition = "2021" -license = "BSD-2-Clause" +license = "MIT" default-run = "minedmap" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e243464..0000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2015-2021, Matthias Schiffer -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 357ef46731fe39dd4bb29ba35d7616aa25c1382a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 12:14:10 +0100 Subject: [PATCH 064/460] types: add helper for division + remainder We frequently require these operations together when converting between bit and byte offsets, or similar purposes. --- src/types.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/types.rs b/src/types.rs index 9aa4b7d..9f0cf0d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ use std::{ fmt::Debug, - ops::{Index, IndexMut}, + ops::{Div, Index, IndexMut, Rem}, }; use itertools::iproduct; @@ -61,3 +61,25 @@ impl IndexMut for ChunkArray { &mut self.0[index.z.0 as usize][index.x.0 as usize] } } + +pub trait DivRem { + type DivOutput; + type RemOutput; + + fn div_rem(self, rhs: Rhs) -> (Self::DivOutput, Self::RemOutput); +} + +impl DivRem for Lhs +where + Self: Div, + Self: Rem, + Self: Copy, + Rhs: Copy, +{ + type DivOutput = >::Output; + type RemOutput = >::Output; + + fn div_rem(self, rhs: Rhs) -> (Self::DivOutput, Self::RemOutput) { + (self / rhs, self % rhs) + } +} From b040a635ed3d51bc304f6f4e05b5f7229903f59b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 12:17:46 +0100 Subject: [PATCH 065/460] types: add types for block and section coordinates --- src/types.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/types.rs b/src/types.rs index 9f0cf0d..450293f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,6 +5,47 @@ use std::{ use itertools::iproduct; +pub const BLOCKS_PER_CHUNK: u8 = 16; + +/// A block X coordinate relative to a chunk +#[derive(Debug, Clone, Copy)] +pub struct BlockX(pub u8); + +/// A block Y coordinate relative to a chunk section +#[derive(Debug, Clone, Copy)] +pub struct BlockY(pub u8); + +/// A block Z coordinate relative to a chunk +#[derive(Debug, Clone, Copy)] +pub struct BlockZ(pub u8); + +#[derive(Clone, Copy)] +pub struct BlockCoords { + pub x: BlockX, + pub y: BlockY, + pub z: BlockZ, +} + +impl BlockCoords { + pub fn offset(&self) -> usize { + const N: usize = BLOCKS_PER_CHUNK as usize; + let x = self.x.0 as usize; + let y = self.y.0 as usize; + let z = self.z.0 as usize; + ((y * N) + z) * N + x + } +} + +impl Debug for BlockCoords { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {}, {})", self.x.0, self.y.0, self.z.0) + } +} + +/// A section Y coordinate +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct SectionY(pub i32); + pub const CHUNKS_PER_REGION: u8 = 32; /// A chunk X coordinate relative to a region From 2d782f25b1082f65a6ae147b0829f5fac6b879ad Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 01:01:53 +0100 Subject: [PATCH 066/460] world: add types to wrap common parts of section data --- src/world/chunk.rs | 111 +++++++++++++++++++++++++++++++++++++++++++ src/world/mod.rs | 2 + src/world/section.rs | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 src/world/chunk.rs create mode 100644 src/world/section.rs diff --git a/src/world/chunk.rs b/src/world/chunk.rs new file mode 100644 index 0000000..d5b30b6 --- /dev/null +++ b/src/world/chunk.rs @@ -0,0 +1,111 @@ +use std::collections::BTreeMap; + +use anyhow::{bail, Context, Result}; + +use super::{ + de, + section::{OldSection, PaletteSection, PaletteSectionBiomes}, +}; +use crate::types::*; + +pub enum Chunk<'a> { + V1_18 { + section_map: BTreeMap, PaletteSectionBiomes<'a>)>, + }, + V1_13 { + section_map: BTreeMap>, + biomes: &'a de::BiomesOld, + }, + Old { + section_map: BTreeMap>, + biomes: &'a de::BiomesOld, + }, + Empty, +} + +impl<'a> Chunk<'a> { + pub fn new(data: &'a de::Chunk) -> Result { + let data_version = data.data_version.unwrap_or_default(); + + match &data.chunk { + de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections), + de::ChunkVariants::Old { level } => Self::new_old(data_version, level), + } + } + + fn new_v1_18(data_version: u32, sections: &'a Vec) -> Result { + let mut section_map = BTreeMap::new(); + + for section in sections { + section_map.insert( + SectionY(section.y), + ( + PaletteSection::new( + data_version, + section.block_states.data.as_ref(), + §ion.block_states.palette, + ) + .with_context(|| format!("Failed to load section at Y={}", section.y))?, + PaletteSectionBiomes::new( + section.biomes.data.as_ref(), + §ion.biomes.palette, + ) + .with_context(|| format!("Failed to load section biomes at Y={}", section.y))?, + ), + ); + } + + Ok(Chunk::V1_18 { section_map }) + } + + fn new_old(data_version: u32, level: &'a de::LevelOld) -> Result { + let mut section_map_v1_13 = BTreeMap::new(); + let mut section_map_old = BTreeMap::new(); + + for section in &level.sections { + match §ion.section { + de::SectionOldVariants::V1_13 { + block_states, + palette, + } => { + section_map_v1_13.insert( + SectionY(section.y.into()), + PaletteSection::new(data_version, Some(block_states), palette) + .with_context(|| { + format!("Failed to load section at Y={}", section.y) + })?, + ); + } + de::SectionOldVariants::Old { blocks, data } => { + section_map_old.insert( + SectionY(section.y.into()), + OldSection::new(blocks, data).with_context(|| { + format!("Failed to load section at Y={}", section.y) + })?, + ); + } + de::SectionOldVariants::Empty {} => {} + } + } + + // TODO Check biomes length + let biomes = level.biomes.as_ref().context("Invalid biome data"); + + Ok( + match (section_map_v1_13.is_empty(), section_map_old.is_empty()) { + (true, true) => Chunk::Empty, + (false, true) => Chunk::V1_13 { + section_map: section_map_v1_13, + biomes: biomes?, + }, + (true, false) => Chunk::Old { + section_map: section_map_old, + biomes: biomes?, + }, + (false, false) => { + bail!("Mixed section versions"); + } + }, + ) + } +} diff --git a/src/world/mod.rs b/src/world/mod.rs index 7bbc60f..ae071e0 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1 +1,3 @@ +pub mod chunk; pub mod de; +pub mod section; diff --git a/src/world/section.rs b/src/world/section.rs new file mode 100644 index 0000000..2ac3945 --- /dev/null +++ b/src/world/section.rs @@ -0,0 +1,95 @@ +use anyhow::{bail, Context, Result}; + +use super::de; + +fn palette_bits(len: usize, min: u8, max: u8) -> Option { + let mut bits = min; + while (1 << bits) < len { + bits += 1; + + if bits > max { + return None; + } + } + + Some(bits) +} + +#[derive(Debug)] +pub struct PaletteSectionBiomes<'a> { + biomes: Option<&'a fastnbt::LongArray>, + palette: &'a Vec, + bits: u8, +} + +impl<'a> PaletteSectionBiomes<'a> { + pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec) -> Result { + let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; + + if let Some(biomes) = biomes { + let biomes_per_word = 64 / bits as usize; + let expected_length = (64 + biomes_per_word - 1) / biomes_per_word; + if biomes.len() != expected_length { + bail!("Invalid section biome data"); + } + } + + Ok(PaletteSectionBiomes { + biomes, + palette, + bits, + }) + } +} + +#[derive(Debug)] +pub struct PaletteSection<'a> { + block_states: Option<&'a fastnbt::LongArray>, + palette: &'a Vec, + bits: u8, + aligned_blocks: bool, +} + +impl<'a> PaletteSection<'a> { + pub fn new( + data_version: u32, + block_states: Option<&'a fastnbt::LongArray>, + palette: &'a Vec, + ) -> Result { + let aligned_blocks = data_version >= 2529; + + let bits = palette_bits(palette.len(), 4, 12).context("Unsupported block palette size")?; + + 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 + } else { + 64 * bits as usize + }; + if block_states.len() != expected_length { + bail!("Invalid section block data"); + } + } + + Ok(Self { + block_states, + palette, + bits, + aligned_blocks, + }) + } +} + +#[derive(Debug)] +pub struct OldSection<'a> { + blocks: &'a fastnbt::ByteArray, + data: &'a fastnbt::ByteArray, +} + +impl<'a> OldSection<'a> { + pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { + // TODO: Check lengths + Ok(Self { blocks, data }) + } +} From c130f3cdae4b50f39072025da5ba81e249cb6b26 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 16:19:41 +0100 Subject: [PATCH 067/460] world: add section iterator An (empty for now) trait is introduced to abstract over the two section types. --- src/world/chunk.rs | 120 ++++++++++++++++++++++++++++++++++++++++++- src/world/section.rs | 6 +++ 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index d5b30b6..5ccb8f9 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -1,10 +1,13 @@ -use std::collections::BTreeMap; +use std::{ + collections::{btree_map, BTreeMap}, + iter::{self, FusedIterator}, +}; use anyhow::{bail, Context, Result}; use super::{ de, - section::{OldSection, PaletteSection, PaletteSectionBiomes}, + section::{OldSection, PaletteSection, PaletteSectionBiomes, Section}, }; use crate::types::*; @@ -23,6 +26,25 @@ pub enum Chunk<'a> { Empty, } +#[derive(Debug, Clone)] +enum SectionIterInner<'a> { + V1_18 { + iter: btree_map::Iter<'a, SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>, + }, + V1_13 { + iter: btree_map::Iter<'a, SectionY, PaletteSection<'a>>, + }, + Old { + iter: btree_map::Iter<'a, SectionY, OldSection<'a>>, + }, + Empty, +} + +#[derive(Debug, Clone)] +pub struct SectionIter<'a> { + inner: SectionIterInner<'a>, +} + impl<'a> Chunk<'a> { pub fn new(data: &'a de::Chunk) -> Result { let data_version = data.data_version.unwrap_or_default(); @@ -108,4 +130,98 @@ impl<'a> Chunk<'a> { }, ) } + + pub fn sections(&self) -> SectionIter { + use SectionIterInner::*; + SectionIter { + inner: match self { + Chunk::V1_18 { section_map } => V1_18 { + iter: section_map.iter(), + }, + Chunk::V1_13 { section_map, .. } => V1_13 { + iter: section_map.iter(), + }, + Chunk::Old { section_map, .. } => Old { + iter: section_map.iter(), + }, + Chunk::Empty => Empty, + }, + } + } } + +trait SectionIterTrait<'a>: + Iterator + + DoubleEndedIterator + + ExactSizeIterator + + FusedIterator +{ +} + +impl<'a, T> SectionIterTrait<'a> for T where + T: Iterator + + DoubleEndedIterator + + ExactSizeIterator + + FusedIterator +{ +} + +impl<'a> SectionIter<'a> { + fn with_iter(&mut self, f: F) -> T + where + F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T, + { + match &mut self.inner { + SectionIterInner::V1_18 { iter } => f( + &mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, §ion.0) }) + ), + SectionIterInner::V1_13 { iter } => { + f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) + } + SectionIterInner::Old { iter } => { + f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) + } + SectionIterInner::Empty => f(&mut iter::empty()), + } + } +} + +impl<'a> Iterator for SectionIter<'a> { + type Item = (SectionY, &'a dyn Section); + + fn next(&mut self) -> Option { + self.with_iter(|iter| iter.next()) + } + + fn size_hint(&self) -> (usize, Option) { + match &self.inner { + SectionIterInner::V1_18 { iter } => iter.size_hint(), + SectionIterInner::V1_13 { iter } => iter.size_hint(), + SectionIterInner::Old { iter } => iter.size_hint(), + SectionIterInner::Empty => (0, Some(0)), + } + } + + fn last(mut self) -> Option { + self.with_iter(|iter| iter.last()) + } +} + +impl<'a> DoubleEndedIterator for SectionIter<'a> { + fn next_back(&mut self) -> Option { + self.with_iter(|iter| iter.next_back()) + } +} + +impl<'a> ExactSizeIterator for SectionIter<'a> { + fn len(&self) -> usize { + match &self.inner { + SectionIterInner::V1_18 { iter } => iter.len(), + SectionIterInner::V1_13 { iter } => iter.len(), + SectionIterInner::Old { iter } => iter.len(), + SectionIterInner::Empty => 0, + } + } +} + +impl<'a> FusedIterator for SectionIter<'a> {} diff --git a/src/world/section.rs b/src/world/section.rs index 2ac3945..3aa5aca 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -15,6 +15,8 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { Some(bits) } +pub trait Section {} + #[derive(Debug)] pub struct PaletteSectionBiomes<'a> { biomes: Option<&'a fastnbt::LongArray>, @@ -81,6 +83,8 @@ impl<'a> PaletteSection<'a> { } } +impl<'a> Section for PaletteSection<'a> {} + #[derive(Debug)] pub struct OldSection<'a> { blocks: &'a fastnbt::ByteArray, @@ -93,3 +97,5 @@ impl<'a> OldSection<'a> { Ok(Self { blocks, data }) } } + +impl<'a> Section for OldSection<'a> {} From 8add7679a30c96e0665ea6937b5bbf41ba1bd6f8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 17:56:44 +0100 Subject: [PATCH 068/460] types: add Eq to coordinate types --- src/types.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/types.rs b/src/types.rs index 450293f..7487a1d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,18 +8,18 @@ use itertools::iproduct; pub const BLOCKS_PER_CHUNK: u8 = 16; /// A block X coordinate relative to a chunk -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockX(pub u8); /// A block Y coordinate relative to a chunk section -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockY(pub u8); /// A block Z coordinate relative to a chunk -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockZ(pub u8); -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct BlockCoords { pub x: BlockX, pub y: BlockY, @@ -49,15 +49,15 @@ pub struct SectionY(pub i32); pub const CHUNKS_PER_REGION: u8 = 32; /// A chunk X coordinate relative to a region -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChunkX(pub u8); /// A chunk Z coordinate relative to a region -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChunkZ(pub u8); /// A pair of chunk coordinates relative to a region -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct ChunkCoords { pub x: ChunkX, pub z: ChunkZ, From 3cee4a4247057dea550582a98a72d27ef4203bbb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 19:02:00 +0100 Subject: [PATCH 069/460] resource: port legacy block type mapping from old implementation --- src/resource/legacy_block_types.rs | 1050 ++++++++++++++++++++++++++++ src/resource/mod.rs | 3 + 2 files changed, 1053 insertions(+) create mode 100644 src/resource/legacy_block_types.rs diff --git a/src/resource/legacy_block_types.rs b/src/resource/legacy_block_types.rs new file mode 100644 index 0000000..6dc7305 --- /dev/null +++ b/src/resource/legacy_block_types.rs @@ -0,0 +1,1050 @@ +const fn simple(id: &str) -> [&str; 16] { + [ + id, id, id, id, id, id, id, id, id, id, id, id, id, id, id, id, + ] +} + +const DEF: &str = "minecraft:air"; +const EMPTY: [&str; 16] = simple(DEF); + +pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ + /* 0 */ + simple("minecraft:air"), + /* 1 */ + [ + "minecraft:stone", + "minecraft:granite", + "minecraft:polished_granite", + "minecraft:diorite", + "minecraft:polished_diorite", + "minecraft:andesite", + "minecraft:polished_andesite", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 2 */ + simple("minecraft:grass_block"), + /* 3 */ + [ + "minecraft:dirt", + "minecraft:coarse_dirt", + "minecraft:podzol", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 4 */ + simple("minecraft:cobblestone"), + /* 5 */ + [ + "minecraft:oak_planks", + "minecraft:spruce_planks", + "minecraft:birch_planks", + "minecraft:jungle_planks", + "minecraft:acacia_planks", + "minecraft:dark_oak_planks", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 6 */ + [ + "minecraft:oak_sapling", + "minecraft:spruce_sapling", + "minecraft:birch_sapling", + "minecraft:jungle_sapling", + "minecraft:acacia_sapling", + "minecraft:dark_oak_sapling", + DEF, + DEF, + "minecraft:oak_sapling", + "minecraft:spruce_sapling", + "minecraft:birch_sapling", + "minecraft:jungle_sapling", + "minecraft:acacia_sapling", + "minecraft:dark_oak_sapling", + DEF, + DEF, + ], + /* 7 */ + simple("minecraft:bedrock"), + /* 8 */ + simple("minecraft:water"), + /* 9 */ + simple("minecraft:water"), + /* 10 */ + simple("minecraft:lava"), + /* 11 */ + simple("minecraft:lava"), + /* 12 */ + [ + "minecraft:sand", + "minecraft:red_sand", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 13 */ + simple("minecraft:gravel"), + /* 14 */ + simple("minecraft:gold_ore"), + /* 15 */ + simple("minecraft:iron_ore"), + /* 16 */ + simple("minecraft:coal_ore"), + /* 17 */ + [ + "minecraft:oak_log", + "minecraft:spruce_log", + "minecraft:birch_log", + "minecraft:jungle_log", + "minecraft:oak_log", + "minecraft:spruce_log", + "minecraft:birch_log", + "minecraft:jungle_log", + "minecraft:oak_log", + "minecraft:spruce_log", + "minecraft:birch_log", + "minecraft:jungle_log", + "minecraft:oak_log", + "minecraft:spruce_log", + "minecraft:birch_log", + "minecraft:jungle_log", + ], + /* 18 */ + [ + "minecraft:oak_leaves", + "minecraft:spruce_leaves", + "minecraft:birch_leaves", + "minecraft:jungle_leaves", + "minecraft:oak_leaves", + "minecraft:spruce_leaves", + "minecraft:birch_leaves", + "minecraft:jungle_leaves", + "minecraft:oak_leaves", + "minecraft:spruce_leaves", + "minecraft:birch_leaves", + "minecraft:jungle_leaves", + "minecraft:oak_leaves", + "minecraft:spruce_leaves", + "minecraft:birch_leaves", + "minecraft:jungle_leaves", + ], + /* 19 */ + simple("minecraft:sponge"), + /* 20 */ + simple("minecraft:glass"), + /* 21 */ + simple("minecraft:lapis_ore"), + /* 22 */ + simple("minecraft:lapis_block"), + /* 23 */ + simple("minecraft:dispenser"), + /* 24 */ + simple("minecraft:sandstone"), + /* 25 */ + simple("minecraft:note_block"), + /* 26 */ + EMPTY, // bed + /* 27 */ + simple("minecraft:powered_rail"), + /* 28 */ + simple("minecraft:detector_rail"), + /* 29 */ + simple("minecraft:sticky_piston"), + /* 30 */ + simple("minecraft:cobweb"), + /* 31 */ + [ + "minecraft:grass", + "minecraft:fern", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 32 */ + simple("minecraft:dead_bush"), + /* 33 */ + simple("minecraft:piston"), + /* 34 */ + simple("minecraft:piston_head"), + /* 35 */ + [ + "minecraft:white_wool", + "minecraft:orange_wool", + "minecraft:magenta_wool", + "minecraft:light_blue_wool", + "minecraft:yellow_wool", + "minecraft:lime_wool", + "minecraft:pink_wool", + "minecraft:gray_wool", + "minecraft:light_gray_wool", + "minecraft:cyan_wool", + "minecraft:purple_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:green_wool", + "minecraft:red_wool", + "minecraft:black_wool", + ], + /* 36 */ + simple("minecraft:moving_piston"), + /* 37 */ + simple("minecraft:dandelion"), + /* 38 */ + [ + "minecraft:poppy", + "minecraft:blue_orchid", + "minecraft:allium", + "minecraft:azure_bluet", + "minecraft:red_tulip", + "minecraft:orange_tulip", + "minecraft:white_tulip", + "minecraft:pink_tulip", + "minecraft:oxeye_daisy", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 39 */ + simple("minecraft:brown_mushroom"), + /* 40 */ + simple("minecraft:red_mushroom"), + /* 41 */ + simple("minecraft:gold_block"), + /* 42 */ + simple("minecraft:iron_block"), + /* 43 */ + [ + "minecraft:smooth_stone_slab", + "minecraft:sandstone_slab", + "minecraft:oak_slab", + "minecraft:cobblestone_slab", + "minecraft:brick_slab", + "minecraft:stone_brick_slab", + "minecraft:nether_brick_slab", + "minecraft:quartz_slab", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 44 */ + [ + "minecraft:smooth_stone_slab", + "minecraft:sandstone_slab", + "minecraft:oak_slab", + "minecraft:cobblestone_slab", + "minecraft:brick_slab", + "minecraft:stone_brick_slab", + "minecraft:nether_brick_slab", + "minecraft:quartz_slab", + "minecraft:stone_slab", + "minecraft:sandstone_slab", + "minecraft:oak_slab", + "minecraft:cobblestone_slab", + "minecraft:brick_slab", + "minecraft:stone_brick_slab", + "minecraft:nether_brick_slab", + "minecraft:quartz_slab", + ], + /* 45 */ + simple("minecraft:bricks"), + /* 46 */ + simple("minecraft:tnt"), + /* 47 */ + simple("minecraft:bookshelf"), + /* 48 */ + simple("minecraft:mossy_cobblestone"), + /* 49 */ + simple("minecraft:obsidian"), + /* 50 */ + [ + DEF, + "minecraft:wall_torch", + "minecraft:wall_torch", + "minecraft:wall_torch", + "minecraft:wall_torch", + "minecraft:torch", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 51 */ + simple("minecraft:fire"), + /* 52 */ + simple("minecraft:spawner"), + /* 53 */ + simple("minecraft:oak_stairs"), + /* 54 */ + simple("minecraft:chest"), + /* 55 */ + simple("minecraft:redstone_wire"), + /* 56 */ + simple("minecraft:diamond_ore"), + /* 57 */ + simple("minecraft:diamond_block"), + /* 58 */ + simple("minecraft:crafting_table"), + /* 59 */ + simple("minecraft:wheat"), + /* 60 */ + simple("minecraft:farmland"), + /* 61 */ + simple("minecraft:furnace"), + /* 62 */ + simple("minecraft:furnace"), + /* 63 */ + simple("minecraft:sign"), + /* 64 */ + simple("minecraft:oak_door"), + /* 65 */ + simple("minecraft:ladder"), + /* 66 */ + simple("minecraft:rail"), + /* 67 */ + simple("minecraft:cobblestone_stairs"), + /* 68 */ + simple("minecraft:wall_sign"), + /* 69 */ + simple("minecraft:lever"), + /* 70 */ + simple("minecraft:stone_pressure_plate"), + /* 71 */ + simple("minecraft:iron_door"), + /* 72 */ + simple("minecraft:oak_pressure_plate"), + /* 73 */ + simple("minecraft:redstone_ore"), + /* 74 */ + simple("minecraft:redstone_ore"), + /* 75 */ + [ + DEF, + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_torch", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 76 */ + [ + DEF, + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_wall_torch", + "minecraft:redstone_torch", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 77 */ + simple("minecraft:stone_button"), + /* 78 */ + simple("minecraft:snow"), + /* 79 */ + simple("minecraft:ice"), + /* 80 */ + simple("minecraft:snow_block"), + /* 81 */ + simple("minecraft:cactus"), + /* 82 */ + simple("minecraft:clay"), + /* 83 */ + simple("minecraft:sugar_cane"), + /* 84 */ + simple("minecraft:jukebox"), + /* 85 */ + simple("minecraft:oak_fence"), + /* 86 */ + simple("minecraft:pumpkin"), + /* 87 */ + simple("minecraft:netherrack"), + /* 88 */ + simple("minecraft:soul_sand"), + /* 89 */ + simple("minecraft:glowstone"), + /* 90 */ + simple("minecraft:nether_portal"), + /* 91 */ + simple("minecraft:pumpkin"), + /* 92 */ + simple("minecraft:cake"), + /* 93 */ + simple("minecraft:repeater"), + /* 94 */ + simple("minecraft:repeater"), + /* 95 */ + [ + "minecraft:white_stained_glass", + "minecraft:orange_stained_glass", + "minecraft:magenta_stained_glass", + "minecraft:light_blue_stained_glass", + "minecraft:yellow_stained_glass", + "minecraft:lime_stained_glass", + "minecraft:pink_stained_glass", + "minecraft:gray_stained_glass", + "minecraft:light_gray_stained_glass", + "minecraft:cyan_stained_glass", + "minecraft:purple_stained_glass", + "minecraft:blue_stained_glass", + "minecraft:brown_stained_glass", + "minecraft:green_stained_glass", + "minecraft:red_stained_glass", + "minecraft:black_stained_glass", + ], + /* 96 */ + simple("minecraft:oak_trapdoor"), + /* 97 */ + [ + "minecraft:infested_stone", + "minecraft:infested_cobblestone", + "minecraft:infested_stone_bricks", + "minecraft:infested_mossy_stone_bricks", + "minecraft:infested_cracked_stone_bricks", + "minecraft:infested_chiseled_stone_bricks", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 98 */ + [ + "minecraft:stone_bricks", + "minecraft:mossy_stone_bricks", + "minecraft:cracked_stone_bricks", + "minecraft:chiseled_stone_bricks", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 99 */ + simple("minecraft:brown_mushroom_block"), + /* 100 */ + simple("minecraft:red_mushroom_block"), + /* 101 */ + simple("minecraft:iron_bars"), + /* 102 */ + simple("minecraft:glass_pane"), + /* 103 */ + simple("minecraft:melon"), + /* 104 */ + simple("minecraft:pumpkin_stem"), + /* 105 */ + simple("minecraft:melon_stem"), + /* 106 */ + simple("minecraft:vine"), + /* 107 */ + simple("minecraft:oak_fence_gate"), + /* 108 */ + simple("minecraft:brick_stairs"), + /* 109 */ + simple("minecraft:stone_brick_stairs"), + /* 110 */ + simple("minecraft:mycelium"), + /* 111 */ + simple("minecraft:lily_pad"), + /* 112 */ + simple("minecraft:nether_bricks"), + /* 113 */ + simple("minecraft:nether_brick_fence"), + /* 114 */ + simple("minecraft:nether_brick_stairs"), + /* 115 */ + simple("minecraft:nether_wart"), + /* 116 */ + simple("minecraft:enchanting_table"), + /* 117 */ + simple("minecraft:brewing_stand"), + /* 118 */ + simple("minecraft:cauldron"), + /* 119 */ + simple("minecraft:end_portal"), + /* 120 */ + simple("minecraft:end_portal_frame"), + /* 121 */ + simple("minecraft:end_stone"), + /* 122 */ + simple("minecraft:dragon_egg"), + /* 123 */ + simple("minecraft:redstone_lamp"), + /* 124 */ + simple("minecraft:redstone_lamp"), + /* 125 */ + [ + "minecraft:oak_slab", + "minecraft:spruce_slab", + "minecraft:birch_slab", + "minecraft:jungle_slab", + "minecraft:acacia_slab", + "minecraft:dark_oak_slab", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 126 */ + [ + "minecraft:oak_slab", + "minecraft:spruce_slab", + "minecraft:birch_slab", + "minecraft:jungle_slab", + "minecraft:acacia_slab", + "minecraft:dark_oak_slab", + DEF, + DEF, + "minecraft:oak_slab", + "minecraft:spruce_slab", + "minecraft:birch_slab", + "minecraft:jungle_slab", + "minecraft:acacia_slab", + "minecraft:dark_oak_slab", + DEF, + DEF, + ], + /* 127 */ + simple("minecraft:cocoa"), + /* 128 */ + simple("minecraft:sandstone_stairs"), + /* 129 */ + simple("minecraft:emerald_ore"), + /* 130 */ + simple("minecraft:ender_chest"), + /* 131 */ + simple("minecraft:tripwire_hook"), + /* 132 */ + simple("minecraft:tripwire"), + /* 133 */ + simple("minecraft:emerald_block"), + /* 134 */ + simple("minecraft:spruce_stairs"), + /* 135 */ + simple("minecraft:birch_stairs"), + /* 136 */ + simple("minecraft:jungle_stairs"), + /* 137 */ + simple("minecraft:command_block"), + /* 138 */ + simple("minecraft:beacon"), + /* 139 */ + [ + "minecraft:cobblestone_wall", + "minecraft:mossy_cobblestone_wall", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 140 */ + simple("minecraft:flower_pot"), + /* 141 */ + simple("minecraft:carrots"), + /* 142 */ + simple("minecraft:potatoes"), + /* 143 */ + EMPTY, + /* 144 */ + EMPTY, + /* 145 */ + [ + "minecraft:anvil", + "minecraft:anvil", + "minecraft:anvil", + "minecraft:anvil", + "minecraft:chipped_anvil", + "minecraft:chipped_anvil", + "minecraft:chipped_anvil", + "minecraft:chipped_anvil", + "minecraft:damaged_anvil", + "minecraft:damaged_anvil", + "minecraft:damaged_anvil", + "minecraft:damaged_anvil", + DEF, + DEF, + DEF, + DEF, + ], + /* 146 */ + simple("minecraft:trapped_chest"), + /* 147 */ + simple("minecraft:light_weighted_pressure_plate"), + /* 148 */ + simple("minecraft:heavy_weighted_pressure_plate"), + /* 149 */ + simple("minecraft:comparator"), + /* 150 */ + simple("minecraft:comparator"), + /* 151 */ + simple("minecraft:daylight_detector"), + /* 152 */ + simple("minecraft:redstone_block"), + /* 153 */ + simple("minecraft:nether_quartz_ore"), + /* 154 */ + simple("minecraft:hopper"), + /* 155 */ + simple("minecraft:quartz_block"), + /* 156 */ + simple("minecraft:quartz_stairs"), + /* 157 */ + simple("minecraft:activator_rail"), + /* 158 */ + simple("minecraft:dropper"), + /* 159 */ + [ + "minecraft:white_terracotta", + "minecraft:orange_terracotta", + "minecraft:magenta_terracotta", + "minecraft:light_blue_terracotta", + "minecraft:yellow_terracotta", + "minecraft:lime_terracotta", + "minecraft:pink_terracotta", + "minecraft:gray_terracotta", + "minecraft:light_gray_terracotta", + "minecraft:cyan_terracotta", + "minecraft:purple_terracotta", + "minecraft:blue_terracotta", + "minecraft:brown_terracotta", + "minecraft:green_terracotta", + "minecraft:red_terracotta", + "minecraft:black_terracotta", + ], + /* 160 */ + [ + "minecraft:white_stained_glass_pane", + "minecraft:orange_stained_glass_pane", + "minecraft:magenta_stained_glass_pane", + "minecraft:light_blue_stained_glass_pane", + "minecraft:yellow_stained_glass_pane", + "minecraft:lime_stained_glass_pane", + "minecraft:pink_stained_glass_pane", + "minecraft:gray_stained_glass_pane", + "minecraft:light_gray_stained_glass_pane", + "minecraft:cyan_stained_glass_pane", + "minecraft:purple_stained_glass_pane", + "minecraft:blue_stained_glass_pane", + "minecraft:brown_stained_glass_pane", + "minecraft:green_stained_glass_pane", + "minecraft:red_stained_glass_pane", + "minecraft:black_stained_glass_pane", + ], + /* 161 */ + [ + "minecraft:acacia_leaves", + "minecraft:dark_oak_leaves", + DEF, + DEF, + "minecraft:acacia_leaves", + "minecraft:dark_oak_leaves", + DEF, + DEF, + "minecraft:acacia_leaves", + "minecraft:dark_oak_leaves", + DEF, + DEF, + "minecraft:acacia_leaves", + "minecraft:dark_oak_leaves", + DEF, + DEF, + ], + /* 162 */ + [ + "minecraft:acacia_log", + "minecraft:dark_oak_log", + DEF, + DEF, + "minecraft:acacia_log", + "minecraft:dark_oak_log", + DEF, + DEF, + "minecraft:acacia_log", + "minecraft:dark_oak_log", + DEF, + DEF, + "minecraft:acacia_log", + "minecraft:dark_oak_log", + DEF, + DEF, + ], + /* 163 */ + simple("minecraft:acacia_stairs"), + /* 164 */ + simple("minecraft:dark_oak_stairs"), + /* 165 */ + simple("minecraft:slime_block"), + /* 166 */ + simple("minecraft:barrier"), + /* 167 */ + simple("minecraft:iron_trapdoor"), + /* 168 */ + [ + "minecraft:prismarine", + "minecraft:prismarine_bricks", + "minecraft:dark_prismarine", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 169 */ + simple("minecraft:sea_lantern"), + /* 170 */ + simple("minecraft:hay_block"), + /* 171 */ + [ + "minecraft:white_carpet", + "minecraft:orange_carpet", + "minecraft:magenta_carpet", + "minecraft:light_blue_carpet", + "minecraft:yellow_carpet", + "minecraft:lime_carpet", + "minecraft:pink_carpet", + "minecraft:gray_carpet", + "minecraft:light_gray_carpet", + "minecraft:cyan_carpet", + "minecraft:purple_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:green_carpet", + "minecraft:red_carpet", + "minecraft:black_carpet", + ], + /* 172 */ + simple("minecraft:terracotta"), + /* 173 */ + simple("minecraft:coal_block"), + /* 174 */ + simple("minecraft:packed_ice"), + /* 175 */ + [ + "minecraft:sunflower", + "minecraft:lilac", + "minecraft:tall_grass", + "minecraft:large_fern", + "minecraft:rose_bush", + "minecraft:peony", + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + DEF, + ], + /* 176 */ + EMPTY, // banner + /* 177 */ + EMPTY, // wall banner + /* 178 */ + simple("minecraft:daylight_detector"), + /* 179 */ + simple("minecraft:red_sandstone"), + /* 180 */ + simple("minecraft:red_sandstone_stairs"), + /* 181 */ + simple("minecraft:red_sandstone_slab"), + /* 182 */ + simple("minecraft:red_sandstone_slab"), + /* 183 */ + simple("minecraft:spruce_fence_gate"), + /* 184 */ + simple("minecraft:birch_fence_gate"), + /* 185 */ + simple("minecraft:jungle_fence_gate"), + /* 186 */ + simple("minecraft:dark_oak_fence_gate"), + /* 187 */ + simple("minecraft:acacia_fence_gate"), + /* 188 */ + simple("minecraft:spruce_fence"), + /* 189 */ + simple("minecraft:birch_fence"), + /* 190 */ + simple("minecraft:jungle_fence"), + /* 191 */ + simple("minecraft:dark_oak_fence"), + /* 192 */ + simple("minecraft:acacia_fence"), + /* 193 */ + simple("minecraft:spruce_door"), + /* 194 */ + simple("minecraft:birch_door"), + /* 195 */ + simple("minecraft:jungle_door"), + /* 196 */ + simple("minecraft:acacia_door"), + /* 197 */ + simple("minecraft:dark_oak_door"), + /* 198 */ + simple("minecraft:end_rod"), + /* 199 */ + simple("minecraft:chorus_plant"), + /* 200 */ + simple("minecraft:chorus_flower"), + /* 201 */ + simple("minecraft:purpur_block"), + /* 202 */ + simple("minecraft:purpur_pillar"), + /* 203 */ + simple("minecraft:purpur_stairs"), + /* 204 */ + simple("minecraft:purpur_slab"), + /* 205 */ + simple("minecraft:purpur_slab"), + /* 206 */ + simple("minecraft:end_stone_bricks"), + /* 207 */ + simple("minecraft:beetroots"), + /* 208 */ + simple("minecraft:grass_path"), + /* 209 */ + simple("minecraft:end_gateway"), + /* 210 */ + simple("minecraft:repeating_command_block"), + /* 211 */ + simple("minecraft:chain_command_block"), + /* 212 */ + simple("minecraft:frosted_ice"), + /* 213 */ + simple("minecraft:magma_block"), + /* 214 */ + simple("minecraft:nether_wart_block"), + /* 215 */ + simple("minecraft:red_nether_bricks"), + /* 216 */ + simple("minecraft:bone_block"), + /* 217 */ + simple("minecraft:structure_void"), + /* 218 */ + simple("minecraft:observer"), + /* 219 */ + simple("minecraft:white_shulker_box"), + /* 220 */ + simple("minecraft:orange_shulker_box"), + /* 221 */ + simple("minecraft:magenta_shulker_box"), + /* 222 */ + simple("minecraft:light_blue_shulker_box"), + /* 223 */ + simple("minecraft:yellow_shulker_box"), + /* 224 */ + simple("minecraft:lime_shulker_box"), + /* 225 */ + simple("minecraft:pink_shulker_box"), + /* 226 */ + simple("minecraft:gray_shulker_box"), + /* 227 */ + simple("minecraft:light_gray_shulker_box"), + /* 228 */ + simple("minecraft:cyan_shulker_box"), + /* 229 */ + simple("minecraft:purple_shulker_box"), + /* 230 */ + simple("minecraft:blue_shulker_box"), + /* 231 */ + simple("minecraft:brown_shulker_box"), + /* 232 */ + simple("minecraft:green_shulker_box"), + /* 233 */ + simple("minecraft:red_shulker_box"), + /* 234 */ + simple("minecraft:black_shulker_box"), + /* 235 */ + simple("minecraft:white_glazed_terracotta"), + /* 236 */ + simple("minecraft:orange_glazed_terracotta"), + /* 237 */ + simple("minecraft:magenta_glazed_terracotta"), + /* 238 */ + simple("minecraft:light_blue_glazed_terracotta"), + /* 239 */ + simple("minecraft:yellow_glazed_terracotta"), + /* 240 */ + simple("minecraft:lime_glazed_terracotta"), + /* 241 */ + simple("minecraft:pink_glazed_terracotta"), + /* 242 */ + simple("minecraft:gray_glazed_terracotta"), + /* 243 */ + simple("minecraft:light_gray_glazed_terracotta"), + /* 244 */ + simple("minecraft:cyan_glazed_terracotta"), + /* 245 */ + simple("minecraft:purple_glazed_terracotta"), + /* 246 */ + simple("minecraft:blue_glazed_terracotta"), + /* 247 */ + simple("minecraft:brown_glazed_terracotta"), + /* 248 */ + simple("minecraft:green_glazed_terracotta"), + /* 249 */ + simple("minecraft:red_glazed_terracotta"), + /* 250 */ + simple("minecraft:black_glazed_terracotta"), + /* 251 */ + [ + "minecraft:white_concrete", + "minecraft:orange_concrete", + "minecraft:magenta_concrete", + "minecraft:light_blue_concrete", + "minecraft:yellow_concrete", + "minecraft:lime_concrete", + "minecraft:pink_concrete", + "minecraft:gray_concrete", + "minecraft:light_gray_concrete", + "minecraft:cyan_concrete", + "minecraft:purple_concrete", + "minecraft:blue_concrete", + "minecraft:brown_concrete", + "minecraft:green_concrete", + "minecraft:red_concrete", + "minecraft:black_concrete", + ], + /* 252 */ + [ + "minecraft:white_concrete_powder", + "minecraft:orange_concrete_powder", + "minecraft:magenta_concrete_powder", + "minecraft:light_blue_concrete_powder", + "minecraft:yellow_concrete_powder", + "minecraft:lime_concrete_powder", + "minecraft:pink_concrete_powder", + "minecraft:gray_concrete_powder", + "minecraft:light_gray_concrete_powder", + "minecraft:cyan_concrete_powder", + "minecraft:purple_concrete_powder", + "minecraft:blue_concrete_powder", + "minecraft:brown_concrete_powder", + "minecraft:green_concrete_powder", + "minecraft:red_concrete_powder", + "minecraft:black_concrete_powder", + ], + /* 253 */ + EMPTY, + /* 254 */ + EMPTY, + /* 255 */ + simple("minecraft:structure_block"), +]; diff --git a/src/resource/mod.rs b/src/resource/mod.rs index cadac86..3dbc10c 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -1,9 +1,12 @@ mod block_types; +mod legacy_block_types; use std::collections::HashMap; use enumflags2::{bitflags, BitFlags}; +pub use legacy_block_types::LEGACY_BLOCK_TYPES; + #[bitflags] #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq)] From b918ff61061d02e548b4f1e5631abef8f26fdfb4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 20:04:31 +0100 Subject: [PATCH 070/460] world/section: add method to get block ID at coordinate --- src/world/section.rs | 74 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index 3aa5aca..8c849f9 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -1,6 +1,7 @@ use anyhow::{bail, Context, Result}; use super::de; +use crate::{resource, types::*}; fn palette_bits(len: usize, min: u8, max: u8) -> Option { let mut bits = min; @@ -15,7 +16,9 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { Some(bits) } -pub trait Section {} +pub trait Section { + fn get_block_id(&self, coords: BlockCoords) -> Result<&str>; +} #[derive(Debug)] pub struct PaletteSectionBiomes<'a> { @@ -81,9 +84,48 @@ impl<'a> PaletteSection<'a> { aligned_blocks, }) } + + fn get_palette_index(&self, coords: BlockCoords) -> usize { + let Some(block_states) = self.block_states else { + return 0; + }; + + let bits = self.bits as usize; + let mask = (1 << bits) - 1; + + let offset = coords.offset(); + + let shifted = if self.aligned_blocks { + let blocks_per_word = 64 / bits; + let (word, shift) = offset.div_rem(blocks_per_word); + block_states[word] as u64 >> (shift * bits) + } else { + let bit_offset = offset * bits; + let (word, bit_shift) = bit_offset.div_rem(64); + + if bit_shift + bits <= 64 { + block_states[word] as u64 >> bit_shift + } else { + let tmp = (block_states[word + 1] as u64 as u128) << 64 + | block_states[word] as u64 as u128; + (tmp >> bit_shift) as u64 + } + }; + + (shifted & mask) as usize + } } -impl<'a> Section for PaletteSection<'a> {} +impl<'a> Section for PaletteSection<'a> { + fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { + let index = self.get_palette_index(coords); + let entry = self + .palette + .get(index) + .context("Palette index out of bounds")?; + Ok(&entry.name) + } +} #[derive(Debug)] pub struct OldSection<'a> { @@ -93,9 +135,31 @@ pub struct OldSection<'a> { impl<'a> OldSection<'a> { pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { - // TODO: Check lengths - Ok(Self { blocks, data }) + const N: usize = BLOCKS_PER_CHUNK as usize; + if blocks.len() != N * N * N { + bail!("Invalid section block data"); + } + if data.len() != N * N * N / 2 { + bail!("Invalid section extra data"); + } + + Ok(OldSection { blocks, data }) } } -impl<'a> Section for OldSection<'a> {} +impl<'a> Section for OldSection<'a> { + fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { + let offset = coords.offset(); + let block = self.blocks[offset] as u8; + + let (data_offset, data_nibble) = offset.div_rem(2); + let data_byte = self.data[data_offset] as u8; + let data = if data_nibble == 1 { + data_byte >> 4 + } else { + data_byte & 0xf + }; + + Ok(resource::LEGACY_BLOCK_TYPES[block as usize][data as usize]) + } +} From 65c39ea1530acfa66384460581af5fb09f6dc090 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 20:17:20 +0100 Subject: [PATCH 071/460] types: make CHUNKS_PER_REGION and BLOCKS_PER_CHUNK usize Having these as usize is more convenient. --- src/types.rs | 16 +++++++++------- src/world/section.rs | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/types.rs b/src/types.rs index 7487a1d..427faa4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,7 +5,7 @@ use std::{ use itertools::iproduct; -pub const BLOCKS_PER_CHUNK: u8 = 16; +pub const BLOCKS_PER_CHUNK: usize = 16; /// A block X coordinate relative to a chunk #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -28,7 +28,7 @@ pub struct BlockCoords { impl BlockCoords { pub fn offset(&self) -> usize { - const N: usize = BLOCKS_PER_CHUNK as usize; + use BLOCKS_PER_CHUNK as N; let x = self.x.0 as usize; let y = self.y.0 as usize; let z = self.z.0 as usize; @@ -46,7 +46,7 @@ impl Debug for BlockCoords { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct SectionY(pub i32); -pub const CHUNKS_PER_REGION: u8 = 32; +pub const CHUNKS_PER_REGION: usize = 32; /// A chunk X coordinate relative to a region #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -70,13 +70,15 @@ impl Debug for ChunkCoords { } #[derive(Debug, Clone, Copy, Default)] -pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION as usize]; CHUNKS_PER_REGION as usize]); +pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { pub fn keys() -> impl Iterator { - iproduct!(0..CHUNKS_PER_REGION, 0..CHUNKS_PER_REGION).map(|(z, x)| ChunkCoords { - x: ChunkX(x), - z: ChunkZ(z), + iproduct!(0..(CHUNKS_PER_REGION as u8), 0..(CHUNKS_PER_REGION as u8)).map(|(z, x)| { + ChunkCoords { + x: ChunkX(x), + z: ChunkZ(z), + } }) } diff --git a/src/world/section.rs b/src/world/section.rs index 8c849f9..281579b 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -135,7 +135,8 @@ pub struct OldSection<'a> { impl<'a> OldSection<'a> { pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { - const N: usize = BLOCKS_PER_CHUNK as usize; + use BLOCKS_PER_CHUNK as N; + if blocks.len() != N * N * N { bail!("Invalid section block data"); } From c34f531546233e9360b68c1da6a272d847f4a354 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 20:20:36 +0100 Subject: [PATCH 072/460] world/section: temporarily rename PaletteSectionBiomes fields These fields are unused for now. Add an underscore to supress linter warnings. --- src/world/section.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index 281579b..265b393 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -22,9 +22,9 @@ pub trait Section { #[derive(Debug)] pub struct PaletteSectionBiomes<'a> { - biomes: Option<&'a fastnbt::LongArray>, - palette: &'a Vec, - bits: u8, + _biomes: Option<&'a fastnbt::LongArray>, + _palette: &'a Vec, + _bits: u8, } impl<'a> PaletteSectionBiomes<'a> { @@ -40,9 +40,9 @@ impl<'a> PaletteSectionBiomes<'a> { } Ok(PaletteSectionBiomes { - biomes, - palette, - bits, + _biomes: biomes, + _palette: palette, + _bits: bits, }) } } From 5ee114ed0aeb2ae71609a6e22234106d94c9f58c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 21:01:28 +0100 Subject: [PATCH 073/460] types: slightly simplify DivRev trait --- src/types.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/types.rs b/src/types.rs index 427faa4..71835dd 100644 --- a/src/types.rs +++ b/src/types.rs @@ -105,11 +105,12 @@ impl IndexMut for ChunkArray { } } -pub trait DivRem { - type DivOutput; - type RemOutput; - - fn div_rem(self, rhs: Rhs) -> (Self::DivOutput, Self::RemOutput); +pub trait DivRem +where + Self: Div, + Self: Rem, +{ + fn div_rem(self, rhs: Rhs) -> (>::Output, >::Output); } impl DivRem for Lhs @@ -119,10 +120,7 @@ where Self: Copy, Rhs: Copy, { - type DivOutput = >::Output; - type RemOutput = >::Output; - - fn div_rem(self, rhs: Rhs) -> (Self::DivOutput, Self::RemOutput) { + fn div_rem(self, rhs: Rhs) -> (>::Output, >::Output) { (self / rhs, self % rhs) } } From 493608ebc8600ef2435f04b58c81fdd79bce5a79 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 20:59:23 +0100 Subject: [PATCH 074/460] treewide: add more documentation --- src/types.rs | 12 ++++++++++++ src/world/chunk.rs | 24 ++++++++++++++++++++++++ src/world/section.rs | 17 +++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/types.rs b/src/types.rs index 71835dd..905f0c0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -19,6 +19,7 @@ pub struct BlockY(pub u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockZ(pub u8); +/// X, Y and Z coordinates of a block in a chunk section #[derive(Clone, Copy, PartialEq, Eq)] pub struct BlockCoords { pub x: BlockX, @@ -27,6 +28,11 @@ pub struct BlockCoords { } impl BlockCoords { + /// Computes a block's offset in various data structures + /// + /// Many chunk data structures store block and biome data in the same + /// order. [BlockCoords::offset] computes the offset at which the data + /// for the block at a given coordinate is stored. pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let x = self.x.0 as usize; @@ -69,6 +75,9 @@ impl Debug for ChunkCoords { } } +/// Generic array for data stored per chunk of a region +/// +/// Includes various convenient iteration functions. #[derive(Debug, Clone, Copy, Default)] pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); @@ -105,11 +114,14 @@ impl IndexMut for ChunkArray { } } +/// Calculate division and remainder at the same time pub trait DivRem where Self: Div, Self: Rem, { + /// Returns the result of the division and remainder operations + /// with the same inputs fn div_rem(self, rhs: Rhs) -> (>::Output, >::Output); } diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 5ccb8f9..e6b2aa1 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -11,41 +11,62 @@ use super::{ }; use crate::types::*; +/// Chunk data structure wrapping a [de::Chunk] for convenient access to +/// block and biome data +#[derive(Debug)] pub enum Chunk<'a> { + /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { section_map: BTreeMap, PaletteSectionBiomes<'a>)>, }, + /// Minecraft v1.13+ chunk + /// + /// Block data is stored in an indexed format with variable bit width + /// (depending on the total numer of distinct block types used in a + /// section), and a palette mapping these indices to namespaced + /// block IDs V1_13 { section_map: BTreeMap>, biomes: &'a de::BiomesOld, }, + /// Original pre-1.13 chunk + /// + /// The original chunk format with fixed 8-bit numeric block IDs Old { section_map: BTreeMap>, biomes: &'a de::BiomesOld, }, + /// Unpopulated chunk without any block data Empty, } +/// Inner data structure of [SectionIter] #[derive(Debug, Clone)] enum SectionIterInner<'a> { + /// Iterator over sections of [Chunk::V1_18] V1_18 { iter: btree_map::Iter<'a, SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>, }, + /// Iterator over sections of [Chunk::V1_13] V1_13 { iter: btree_map::Iter<'a, SectionY, PaletteSection<'a>>, }, + /// Iterator over sections of [Chunk::Old] Old { iter: btree_map::Iter<'a, SectionY, OldSection<'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: SectionIterInner<'a>, } impl<'a> Chunk<'a> { + /// Creates a new [Chunk] from a deserialized [de::Chunk] pub fn new(data: &'a de::Chunk) -> Result { let data_version = data.data_version.unwrap_or_default(); @@ -55,6 +76,7 @@ impl<'a> Chunk<'a> { } } + /// [Chunk::new] implementation for Minecraft v1.18+ chunks fn new_v1_18(data_version: u32, sections: &'a Vec) -> Result { let mut section_map = BTreeMap::new(); @@ -80,6 +102,7 @@ impl<'a> Chunk<'a> { Ok(Chunk::V1_18 { section_map }) } + /// [Chunk::new] implementation for all pre-1.18 chunk variants fn new_old(data_version: u32, level: &'a de::LevelOld) -> Result { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_old = BTreeMap::new(); @@ -131,6 +154,7 @@ impl<'a> Chunk<'a> { ) } + /// Returns an interator over the chunk's sections and their Y coordinates pub fn sections(&self) -> SectionIter { use SectionIterInner::*; SectionIter { diff --git a/src/world/section.rs b/src/world/section.rs index 265b393..78201a1 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -3,6 +3,11 @@ use anyhow::{bail, Context, Result}; use super::de; use crate::{resource, types::*}; +/// Determine the number of bits required for indexing into a palette of a given length +/// +/// This is basically a base-2 logarithm, with clamping to a minimum value and +/// check against a maximum value. If the result would be greater than the passed +/// `max` value, [None] is returned. fn palette_bits(len: usize, min: u8, max: u8) -> Option { let mut bits = min; while (1 << bits) < len { @@ -16,10 +21,16 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { Some(bits) } +/// Trait for common functions of [PaletteSection] and [OldSection] pub trait Section { fn get_block_id(&self, coords: BlockCoords) -> Result<&str>; } +/// Minecraft v1.18+ section biome data +/// +/// The biome data is part of the section structure in Minecraft v1.18+, with +/// the biomes laid out as an array of indices into a palette, similar to the +/// v1.13+ block data. #[derive(Debug)] pub struct PaletteSectionBiomes<'a> { _biomes: Option<&'a fastnbt::LongArray>, @@ -28,6 +39,7 @@ pub struct PaletteSectionBiomes<'a> { } impl<'a> PaletteSectionBiomes<'a> { + /// Constructs a new [PaletteSectionBiomes] from deserialized data structures pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec) -> Result { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; @@ -47,6 +59,7 @@ impl<'a> PaletteSectionBiomes<'a> { } } +/// Minecraft v1.13+ section block data #[derive(Debug)] pub struct PaletteSection<'a> { block_states: Option<&'a fastnbt::LongArray>, @@ -56,6 +69,7 @@ pub struct PaletteSection<'a> { } impl<'a> PaletteSection<'a> { + /// Constructs a new [PaletteSection] from deserialized data structures pub fn new( data_version: u32, block_states: Option<&'a fastnbt::LongArray>, @@ -85,6 +99,7 @@ impl<'a> PaletteSection<'a> { }) } + /// Looks up the block type palette index at the given coordinates fn get_palette_index(&self, coords: BlockCoords) -> usize { let Some(block_states) = self.block_states else { return 0; @@ -127,6 +142,7 @@ impl<'a> Section for PaletteSection<'a> { } } +/// Pre-1.13 section block data #[derive(Debug)] pub struct OldSection<'a> { blocks: &'a fastnbt::ByteArray, @@ -134,6 +150,7 @@ pub struct OldSection<'a> { } impl<'a> OldSection<'a> { + /// Constructs a new [OldSection] from deserialized data structures pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { use BLOCKS_PER_CHUNK as N; From 9146c06bec5363c0ca3f81036f10c0b4f0655b6d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 22:54:43 +0100 Subject: [PATCH 075/460] treewide: rename "old" data structures to "v0" "v0" doesn't refer to a specific version of Minecraft; it is just the oldest data format supported by MinedMap. --- src/world/chunk.rs | 72 +++++++++++++++++++++----------------------- src/world/de.rs | 26 ++++++++-------- src/world/section.rs | 28 ++++++++--------- 3 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index e6b2aa1..de0726b 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -7,7 +7,7 @@ use anyhow::{bail, Context, Result}; use super::{ de, - section::{OldSection, PaletteSection, PaletteSectionBiomes, Section}, + section::{BiomesV18, Section, SectionV0, SectionV1_13}, }; use crate::types::*; @@ -17,7 +17,7 @@ use crate::types::*; pub enum Chunk<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { - section_map: BTreeMap, PaletteSectionBiomes<'a>)>, + section_map: BTreeMap, BiomesV18<'a>)>, }, /// Minecraft v1.13+ chunk /// @@ -26,15 +26,15 @@ pub enum Chunk<'a> { /// section), and a palette mapping these indices to namespaced /// block IDs V1_13 { - section_map: BTreeMap>, - biomes: &'a de::BiomesOld, + section_map: BTreeMap>, + biomes: &'a de::BiomesV0, }, /// Original pre-1.13 chunk /// /// The original chunk format with fixed 8-bit numeric block IDs - Old { - section_map: BTreeMap>, - biomes: &'a de::BiomesOld, + V0 { + section_map: BTreeMap>, + biomes: &'a de::BiomesV0, }, /// Unpopulated chunk without any block data Empty, @@ -45,15 +45,15 @@ pub enum Chunk<'a> { enum SectionIterInner<'a> { /// Iterator over sections of [Chunk::V1_18] V1_18 { - iter: btree_map::Iter<'a, SectionY, (PaletteSection<'a>, PaletteSectionBiomes<'a>)>, + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV18<'a>)>, }, /// Iterator over sections of [Chunk::V1_13] V1_13 { - iter: btree_map::Iter<'a, SectionY, PaletteSection<'a>>, + iter: btree_map::Iter<'a, SectionY, SectionV1_13<'a>>, }, - /// Iterator over sections of [Chunk::Old] - Old { - iter: btree_map::Iter<'a, SectionY, OldSection<'a>>, + /// Iterator over sections of [Chunk::V0] + V0 { + iter: btree_map::Iter<'a, SectionY, SectionV0<'a>>, }, /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) Empty, @@ -72,7 +72,7 @@ impl<'a> Chunk<'a> { match &data.chunk { de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections), - de::ChunkVariants::Old { level } => Self::new_old(data_version, level), + de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level), } } @@ -84,17 +84,16 @@ impl<'a> Chunk<'a> { section_map.insert( SectionY(section.y), ( - PaletteSection::new( + SectionV1_13::new( data_version, section.block_states.data.as_ref(), §ion.block_states.palette, ) .with_context(|| format!("Failed to load section at Y={}", section.y))?, - PaletteSectionBiomes::new( - section.biomes.data.as_ref(), - §ion.biomes.palette, - ) - .with_context(|| format!("Failed to load section biomes at Y={}", section.y))?, + BiomesV18::new(section.biomes.data.as_ref(), §ion.biomes.palette) + .with_context(|| { + format!("Failed to load section biomes at Y={}", section.y) + })?, ), ); } @@ -103,33 +102,32 @@ impl<'a> Chunk<'a> { } /// [Chunk::new] implementation for all pre-1.18 chunk variants - fn new_old(data_version: u32, level: &'a de::LevelOld) -> Result { + fn new_v0(data_version: u32, level: &'a de::LevelV0) -> Result { let mut section_map_v1_13 = BTreeMap::new(); - let mut section_map_old = BTreeMap::new(); + let mut section_map_v0 = BTreeMap::new(); for section in &level.sections { match §ion.section { - de::SectionOldVariants::V1_13 { + de::SectionV0Variants::V1_13 { block_states, palette, } => { section_map_v1_13.insert( SectionY(section.y.into()), - PaletteSection::new(data_version, Some(block_states), palette) - .with_context(|| { - format!("Failed to load section at Y={}", section.y) - })?, + SectionV1_13::new(data_version, Some(block_states), palette).with_context( + || format!("Failed to load section at Y={}", section.y), + )?, ); } - de::SectionOldVariants::Old { blocks, data } => { - section_map_old.insert( + de::SectionV0Variants::V0 { blocks, data } => { + section_map_v0.insert( SectionY(section.y.into()), - OldSection::new(blocks, data).with_context(|| { + SectionV0::new(blocks, data).with_context(|| { format!("Failed to load section at Y={}", section.y) })?, ); } - de::SectionOldVariants::Empty {} => {} + de::SectionV0Variants::Empty {} => {} } } @@ -137,14 +135,14 @@ impl<'a> Chunk<'a> { let biomes = level.biomes.as_ref().context("Invalid biome data"); Ok( - match (section_map_v1_13.is_empty(), section_map_old.is_empty()) { + match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { (true, true) => Chunk::Empty, (false, true) => Chunk::V1_13 { section_map: section_map_v1_13, biomes: biomes?, }, - (true, false) => Chunk::Old { - section_map: section_map_old, + (true, false) => Chunk::V0 { + section_map: section_map_v0, biomes: biomes?, }, (false, false) => { @@ -165,7 +163,7 @@ impl<'a> Chunk<'a> { Chunk::V1_13 { section_map, .. } => V1_13 { iter: section_map.iter(), }, - Chunk::Old { section_map, .. } => Old { + Chunk::V0 { section_map, .. } => V0 { iter: section_map.iter(), }, Chunk::Empty => Empty, @@ -202,7 +200,7 @@ impl<'a> SectionIter<'a> { SectionIterInner::V1_13 { iter } => { f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) } - SectionIterInner::Old { iter } => { + SectionIterInner::V0 { iter } => { f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) } SectionIterInner::Empty => f(&mut iter::empty()), @@ -221,7 +219,7 @@ impl<'a> Iterator for SectionIter<'a> { match &self.inner { SectionIterInner::V1_18 { iter } => iter.size_hint(), SectionIterInner::V1_13 { iter } => iter.size_hint(), - SectionIterInner::Old { iter } => iter.size_hint(), + SectionIterInner::V0 { iter } => iter.size_hint(), SectionIterInner::Empty => (0, Some(0)), } } @@ -242,7 +240,7 @@ impl<'a> ExactSizeIterator for SectionIter<'a> { match &self.inner { SectionIterInner::V1_18 { iter } => iter.len(), SectionIterInner::V1_13 { iter } => iter.len(), - SectionIterInner::Old { iter } => iter.len(), + SectionIterInner::V0 { iter } => iter.len(), SectionIterInner::Empty => 0, } } diff --git a/src/world/de.rs b/src/world/de.rs index ead4687..844bd29 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -34,37 +34,37 @@ pub struct SectionV1_18 { pub block_light: Option, } -/// Version-specific part of a pre-1.18 [Section](SectionOld) +/// Version-specific part of a pre-1.18 [Section](SectionV0) #[derive(Debug, Deserialize)] #[serde(untagged)] -pub enum SectionOldVariants { +pub enum SectionV0Variants { #[serde(rename_all = "PascalCase")] V1_13 { block_states: fastnbt::LongArray, palette: Vec, }, #[serde(rename_all = "PascalCase")] - Old { + V0 { blocks: fastnbt::ByteArray, data: fastnbt::ByteArray, }, Empty {}, } -/// Pre-1.18 section element found in the [Level](LevelOld) compound +/// Pre-1.18 section element found in the [Level](LevelV0) compound #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] -pub struct SectionOld { +pub struct SectionV0 { pub y: i8, pub block_light: Option, #[serde(flatten)] - pub section: SectionOldVariants, + pub section: SectionV0Variants, } -/// Pre-1.18 biome fields found in the [Level](LevelOld) compound +/// Pre-1.18 biome fields found in the [Level](LevelV0) compound #[derive(Debug, Deserialize)] #[serde(untagged)] -pub enum BiomesOld { +pub enum BiomesV0 { IntArray(fastnbt::IntArray), ByteArray(fastnbt::ByteArray), } @@ -72,10 +72,10 @@ pub enum BiomesOld { /// `Level` compound element found in pre-1.18 [chunks](Chunk) #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] -pub struct LevelOld { +pub struct LevelV0 { #[serde(default)] - pub sections: Vec, - pub biomes: Option, + pub sections: Vec, + pub biomes: Option, } /// Version-specific part of a [Chunk] compound @@ -86,8 +86,8 @@ pub enum ChunkVariants { sections: Vec, }, #[serde(rename_all = "PascalCase")] - Old { - level: LevelOld, + V0 { + level: LevelV0, }, } diff --git a/src/world/section.rs b/src/world/section.rs index 78201a1..dbcf6ff 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -21,7 +21,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { Some(bits) } -/// Trait for common functions of [PaletteSection] and [OldSection] +/// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section { fn get_block_id(&self, coords: BlockCoords) -> Result<&str>; } @@ -32,14 +32,14 @@ pub trait Section { /// the biomes laid out as an array of indices into a palette, similar to the /// v1.13+ block data. #[derive(Debug)] -pub struct PaletteSectionBiomes<'a> { +pub struct BiomesV18<'a> { _biomes: Option<&'a fastnbt::LongArray>, _palette: &'a Vec, _bits: u8, } -impl<'a> PaletteSectionBiomes<'a> { - /// Constructs a new [PaletteSectionBiomes] from deserialized data structures +impl<'a> BiomesV18<'a> { + /// Constructs a new [BiomesV18] from deserialized data structures pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec) -> Result { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; @@ -51,7 +51,7 @@ impl<'a> PaletteSectionBiomes<'a> { } } - Ok(PaletteSectionBiomes { + Ok(BiomesV18 { _biomes: biomes, _palette: palette, _bits: bits, @@ -61,15 +61,15 @@ impl<'a> PaletteSectionBiomes<'a> { /// Minecraft v1.13+ section block data #[derive(Debug)] -pub struct PaletteSection<'a> { +pub struct SectionV1_13<'a> { block_states: Option<&'a fastnbt::LongArray>, palette: &'a Vec, bits: u8, aligned_blocks: bool, } -impl<'a> PaletteSection<'a> { - /// Constructs a new [PaletteSection] from deserialized data structures +impl<'a> SectionV1_13<'a> { + /// Constructs a new [SectionV1_13] from deserialized data structures pub fn new( data_version: u32, block_states: Option<&'a fastnbt::LongArray>, @@ -131,7 +131,7 @@ impl<'a> PaletteSection<'a> { } } -impl<'a> Section for PaletteSection<'a> { +impl<'a> Section for SectionV1_13<'a> { fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { let index = self.get_palette_index(coords); let entry = self @@ -144,13 +144,13 @@ impl<'a> Section for PaletteSection<'a> { /// Pre-1.13 section block data #[derive(Debug)] -pub struct OldSection<'a> { +pub struct SectionV0<'a> { blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray, } -impl<'a> OldSection<'a> { - /// Constructs a new [OldSection] from deserialized data structures +impl<'a> SectionV0<'a> { + /// Constructs a new [SectionV0] from deserialized data structures pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { use BLOCKS_PER_CHUNK as N; @@ -161,11 +161,11 @@ impl<'a> OldSection<'a> { bail!("Invalid section extra data"); } - Ok(OldSection { blocks, data }) + Ok(SectionV0 { blocks, data }) } } -impl<'a> Section for OldSection<'a> { +impl<'a> Section for SectionV0<'a> { fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { let offset = coords.offset(); let block = self.blocks[offset] as u8; From 1049aad03d849d3fc440ce2db70f8ca69314ff22 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 22:59:28 +0100 Subject: [PATCH 076/460] Update dependencies --- Cargo.lock | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d40e13..cddf403 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "bitflags" @@ -34,9 +34,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cesu8" @@ -167,24 +167,21 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "io-lifetimes" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", "windows-sys", @@ -192,9 +189,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" dependencies = [ "hermit-abi", "io-lifetimes", @@ -284,9 +281,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -302,9 +299,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.7" +version = "0.36.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", "errno", @@ -325,9 +322,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] @@ -414,9 +411,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", From 96736bd7ed41ee84d2cbfb69924062068ab59250 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 23:07:55 +0100 Subject: [PATCH 077/460] Replace DivRem trait with num-integer crate --- Cargo.lock | 26 ++++++++++++++++++++++++++ Cargo.toml | 1 + src/types.rs | 25 +------------------------ src/world/section.rs | 7 ++++--- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cddf403..3efed67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,12 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" @@ -231,6 +237,7 @@ dependencies = [ "fastnbt", "flate2", "itertools", + "num-integer", "serde", ] @@ -243,6 +250,25 @@ dependencies = [ "adler", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.17.0" diff --git a/Cargo.toml b/Cargo.toml index 4c6ee7f..b5ef027 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,5 @@ enumflags2 = "0.7.5" fastnbt = "2.3.2" flate2 = "1.0.25" itertools = "0.10.5" +num-integer = "0.1.45" serde = "1.0.152" diff --git a/src/types.rs b/src/types.rs index 905f0c0..9a1c24f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ use std::{ fmt::Debug, - ops::{Div, Index, IndexMut, Rem}, + ops::{Index, IndexMut}, }; use itertools::iproduct; @@ -113,26 +113,3 @@ impl IndexMut for ChunkArray { &mut self.0[index.z.0 as usize][index.x.0 as usize] } } - -/// Calculate division and remainder at the same time -pub trait DivRem -where - Self: Div, - Self: Rem, -{ - /// Returns the result of the division and remainder operations - /// with the same inputs - fn div_rem(self, rhs: Rhs) -> (>::Output, >::Output); -} - -impl DivRem for Lhs -where - Self: Div, - Self: Rem, - Self: Copy, - Rhs: Copy, -{ - fn div_rem(self, rhs: Rhs) -> (>::Output, >::Output) { - (self / rhs, self % rhs) - } -} diff --git a/src/world/section.rs b/src/world/section.rs index dbcf6ff..b8d4ae7 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -1,4 +1,5 @@ use anyhow::{bail, Context, Result}; +use num_integer::div_rem; use super::de; use crate::{resource, types::*}; @@ -112,11 +113,11 @@ impl<'a> SectionV1_13<'a> { let shifted = if self.aligned_blocks { let blocks_per_word = 64 / bits; - let (word, shift) = offset.div_rem(blocks_per_word); + let (word, shift) = div_rem(offset, blocks_per_word); block_states[word] as u64 >> (shift * bits) } else { let bit_offset = offset * bits; - let (word, bit_shift) = bit_offset.div_rem(64); + let (word, bit_shift) = div_rem(bit_offset, 64); if bit_shift + bits <= 64 { block_states[word] as u64 >> bit_shift @@ -170,7 +171,7 @@ impl<'a> Section for SectionV0<'a> { let offset = coords.offset(); let block = self.blocks[offset] as u8; - let (data_offset, data_nibble) = offset.div_rem(2); + let (data_offset, data_nibble) = div_rem(offset, 2); let data_byte = self.data[data_offset] as u8; let data = if data_nibble == 1 { data_byte >> 4 From 9f8446885ee1f5ce8d77d76a3f778a62003820d4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Feb 2023 23:36:58 +0100 Subject: [PATCH 078/460] treewide: remove get_ prefix from function names Follow the conventions of the std library. --- src/resource/mod.rs | 2 +- src/world/section.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 3dbc10c..24549c3 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -28,7 +28,7 @@ pub struct BlockType { pub color: BlockColor, } -pub fn get_block_types() -> HashMap { +pub fn block_types() -> HashMap { block_types::BLOCK_TYPES .iter() .map(|(k, v)| (String::from(*k), *v)) diff --git a/src/world/section.rs b/src/world/section.rs index b8d4ae7..e59daba 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -24,7 +24,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { /// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section { - fn get_block_id(&self, coords: BlockCoords) -> Result<&str>; + fn block_id_at(&self, coords: BlockCoords) -> Result<&str>; } /// Minecraft v1.18+ section biome data @@ -101,7 +101,7 @@ impl<'a> SectionV1_13<'a> { } /// Looks up the block type palette index at the given coordinates - fn get_palette_index(&self, coords: BlockCoords) -> usize { + fn palette_index_at(&self, coords: BlockCoords) -> usize { let Some(block_states) = self.block_states else { return 0; }; @@ -133,8 +133,8 @@ impl<'a> SectionV1_13<'a> { } impl<'a> Section for SectionV1_13<'a> { - fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { - let index = self.get_palette_index(coords); + fn block_id_at(&self, coords: BlockCoords) -> Result<&str> { + let index = self.palette_index_at(coords); let entry = self .palette .get(index) @@ -167,7 +167,7 @@ impl<'a> SectionV0<'a> { } impl<'a> Section for SectionV0<'a> { - fn get_block_id(&self, coords: BlockCoords) -> Result<&str> { + fn block_id_at(&self, coords: BlockCoords) -> Result<&str> { let offset = coords.offset(); let block = self.blocks[offset] as u8; From 102baa91979269a4d66e8f0b6c6530d62747f198 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 13 Feb 2023 00:02:43 +0100 Subject: [PATCH 079/460] types: add iter() associated function to coordinate newtypes --- src/types.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/types.rs b/src/types.rs index 9a1c24f..765ed39 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,23 +1,43 @@ use std::{ fmt::Debug, + iter::FusedIterator, ops::{Index, IndexMut}, }; use itertools::iproduct; +macro_rules! coord_impl { + ($t:ident, $max:expr) => { + impl $t { + /// Returns an iterator over all possible values of the type + pub fn iter() -> impl Iterator + + DoubleEndedIterator + + ExactSizeIterator + + FusedIterator + + Clone + + Debug { + (0..$max as u8).map($t) + } + } + }; +} + pub const BLOCKS_PER_CHUNK: usize = 16; /// A block X coordinate relative to a chunk #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockX(pub u8); +coord_impl!(BlockX, BLOCKS_PER_CHUNK); /// A block Y coordinate relative to a chunk section #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockY(pub u8); +coord_impl!(BlockY, BLOCKS_PER_CHUNK); /// A block Z coordinate relative to a chunk #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BlockZ(pub u8); +coord_impl!(BlockZ, BLOCKS_PER_CHUNK); /// X, Y and Z coordinates of a block in a chunk section #[derive(Clone, Copy, PartialEq, Eq)] @@ -57,10 +77,12 @@ pub const CHUNKS_PER_REGION: usize = 32; /// A chunk X coordinate relative to a region #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChunkX(pub u8); +coord_impl!(ChunkX, CHUNKS_PER_REGION); /// A chunk Z coordinate relative to a region #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChunkZ(pub u8); +coord_impl!(ChunkZ, CHUNKS_PER_REGION); /// A pair of chunk coordinates relative to a region #[derive(Clone, Copy, PartialEq, Eq)] @@ -83,12 +105,7 @@ pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { pub fn keys() -> impl Iterator { - iproduct!(0..(CHUNKS_PER_REGION as u8), 0..(CHUNKS_PER_REGION as u8)).map(|(z, x)| { - ChunkCoords { - x: ChunkX(x), - z: ChunkZ(z), - } - }) + iproduct!(ChunkZ::iter(), ChunkX::iter()).map(|(z, x)| ChunkCoords { x, z }) } pub fn values(&self) -> impl Iterator { From db289bc077b10c9ba48b12b05dd48d103f1b79b3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 13 Feb 2023 00:11:36 +0100 Subject: [PATCH 080/460] resource: rename BlockFlags to BlockFlag The enum only holds a single flag at a time. --- resource/generate.py | 2 +- src/resource/block_types.rs | 1806 +++++++++++++++++------------------ src/resource/mod.rs | 4 +- 3 files changed, 906 insertions(+), 906 deletions(-) diff --git a/resource/generate.py b/resource/generate.py index 7e6ee09..d91df98 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -34,7 +34,7 @@ with open(sys.argv[2], 'w') as f: flags.append('Spruce') if info['water']: flags.append('Water') - flags = 'make_bitflags!(BlockFlags::{' + '|'.join(flags) + '})' + flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' print('\t("%s", BlockType { flags: %s, color: BlockColor(%u, %u, %u) }),' % ( name, diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index 94d1e2b..5b975c2 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -6,6321 +6,6321 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ ( "minecraft:acacia_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:acacia_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(167, 95, 60), }, ), ( "minecraft:acacia_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(149, 148, 148), }, ), ( "minecraft:acacia_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 88, 55), }, ), ( "minecraft:acacia_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 23), }, ), ( "minecraft:acacia_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( "minecraft:acacia_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(156, 87, 51), }, ), ( "minecraft:acacia_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:acacia_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 96, 86), }, ), ( "minecraft:activator_rail", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 87, 74), }, ), ( "minecraft:air", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:allium", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:amethyst_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(133, 97, 191), }, ), ( "minecraft:amethyst_cluster", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 126, 207), }, ), ( "minecraft:ancient_debris", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 66, 58), }, ), ( "minecraft:andesite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( "minecraft:andesite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( "minecraft:andesite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( "minecraft:andesite_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( "minecraft:anvil", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( "minecraft:attached_melon_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(141, 142, 141), }, ), ( "minecraft:attached_pumpkin_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(139, 139, 139), }, ), ( "minecraft:azalea", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 124, 47), }, ), ( "minecraft:azalea_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 114, 44), }, ), ( "minecraft:azure_bluet", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:bamboo", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 144, 19), }, ), ( "minecraft:bamboo_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:barrel", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 100, 58), }, ), ( "minecraft:barrier", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:basalt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 81, 86), }, ), ( "minecraft:beacon", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 220, 215), }, ), ( "minecraft:bedrock", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 85, 85), }, ), ( "minecraft:bee_nest", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(202, 160, 74), }, ), ( "minecraft:beehive", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(180, 146, 90), }, ), ( "minecraft:beetroots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 91, 30), }, ), ( "minecraft:bell", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(253, 235, 110), }, ), ( "minecraft:big_dripleaf", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 141, 51), }, ), ( "minecraft:big_dripleaf_stem", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:birch_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:birch_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 209, 176), }, ), ( "minecraft:birch_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Birch}), + flags: make_bitflags!(BlockFlag::{Opaque|Birch}), color: BlockColor(130, 129, 130), }, ), ( "minecraft:birch_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(193, 179, 135), }, ), ( "minecraft:birch_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 160, 79), }, ), ( "minecraft:birch_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( "minecraft:birch_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 194, 157), }, ), ( "minecraft:birch_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:birch_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 215, 210), }, ), ( "minecraft:black_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:black_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:black_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:black_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:black_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 21, 25), }, ), ( "minecraft:black_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(8, 10, 15), }, ), ( "minecraft:black_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 26, 31), }, ), ( "minecraft:black_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(67, 30, 32), }, ), ( "minecraft:black_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 25, 29), }, ), ( "minecraft:black_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 25, 25), }, ), ( "minecraft:black_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(24, 24, 24), }, ), ( "minecraft:black_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(37, 22, 16), }, ), ( "minecraft:black_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:black_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 21, 25), }, ), ( "minecraft:blackstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( "minecraft:blackstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( "minecraft:blackstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( "minecraft:blackstone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( "minecraft:blast_furnace", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 81), }, ), ( "minecraft:blue_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:blue_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:blue_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:blue_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:blue_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 57, 157), }, ), ( "minecraft:blue_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 46, 143), }, ), ( "minecraft:blue_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 73, 166), }, ), ( "minecraft:blue_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 64, 139), }, ), ( "minecraft:blue_ice", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(116, 167, 253), }, ), ( "minecraft:blue_orchid", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:blue_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 45, 140), }, ), ( "minecraft:blue_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 76, 178), }, ), ( "minecraft:blue_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 73, 171), }, ), ( "minecraft:blue_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 59, 91), }, ), ( "minecraft:blue_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:blue_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 57, 157), }, ), ( "minecraft:bone_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(209, 206, 179), }, ), ( "minecraft:bookshelf", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:brain_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brain_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 91, 159), }, ), ( "minecraft:brain_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brain_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brewing_stand", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 101, 81), }, ), ( "minecraft:brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( "minecraft:brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( "minecraft:brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( "minecraft:bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( "minecraft:brown_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brown_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brown_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brown_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:brown_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 71, 40), }, ), ( "minecraft:brown_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(96, 59, 31), }, ), ( "minecraft:brown_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 84, 53), }, ), ( "minecraft:brown_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 106, 85), }, ), ( "minecraft:brown_mushroom", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brown_mushroom_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 111, 81), }, ), ( "minecraft:brown_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 66, 35), }, ), ( "minecraft:brown_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 76, 51), }, ), ( "minecraft:brown_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 73, 48), }, ), ( "minecraft:brown_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 51, 35), }, ), ( "minecraft:brown_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:brown_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 71, 40), }, ), ( "minecraft:bubble_column", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Water}), + flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: BlockColor(177, 177, 177), }, ), ( "minecraft:bubble_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:bubble_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 26, 162), }, ), ( "minecraft:bubble_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:bubble_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:budding_amethyst", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 96, 186), }, ), ( "minecraft:cactus", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 127, 43), }, ), ( "minecraft:cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:calcite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 224, 220), }, ), ( "minecraft:campfire", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 88, 54), }, ), ( "minecraft:candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:carrots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 124, 37), }, ), ( "minecraft:cartography_table", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 87, 67), }, ), ( "minecraft:carved_pumpkin", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(198, 118, 24), }, ), ( "minecraft:cauldron", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( "minecraft:cave_air", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cave_vines", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 109, 40), }, ), ( "minecraft:cave_vines_plant", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 101, 38), }, ), ( "minecraft:chain", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:chain_command_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 161, 147), }, ), ( "minecraft:chest", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:chipped_anvil", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( "minecraft:chiseled_deepslate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 54), }, ), ( "minecraft:chiseled_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 23, 28), }, ), ( "minecraft:chiseled_polished_blackstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:chiseled_quartz_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(231, 226, 218), }, ), ( "minecraft:chiseled_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:chiseled_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:chiseled_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 118, 119), }, ), ( "minecraft:chorus_flower", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(151, 120, 151), }, ), ( "minecraft:chorus_plant", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 57, 93), }, ), ( "minecraft:clay", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 166, 179), }, ), ( "minecraft:coal_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(16, 15, 15), }, ), ( "minecraft:coal_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(105, 105, 105), }, ), ( "minecraft:coarse_dirt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 85, 59), }, ), ( "minecraft:cobbled_deepslate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( "minecraft:cobbled_deepslate_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( "minecraft:cobbled_deepslate_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( "minecraft:cobbled_deepslate_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( "minecraft:cobblestone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( "minecraft:cobblestone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( "minecraft:cobblestone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( "minecraft:cobblestone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( "minecraft:cobweb", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 233, 234), }, ), ( "minecraft:cocoa", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(156, 94, 43), }, ), ( "minecraft:command_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 136, 108), }, ), ( "minecraft:comparator", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 161, 159), }, ), ( "minecraft:composter", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 61, 23), }, ), ( "minecraft:conduit", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(159, 139, 113), }, ), ( "minecraft:copper_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 107, 79), }, ), ( "minecraft:copper_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 125, 120), }, ), ( "minecraft:cornflower", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cracked_deepslate_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(64, 64, 65), }, ), ( "minecraft:cracked_deepslate_tiles", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 52, 52), }, ), ( "minecraft:cracked_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(40, 20, 23), }, ), ( "minecraft:cracked_polished_blackstone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 37, 43), }, ), ( "minecraft:cracked_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 118), }, ), ( "minecraft:crafting_table", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 73, 42), }, ), ( "minecraft:creeper_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:creeper_wall_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:crimson_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:crimson_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 54, 79), }, ), ( "minecraft:crimson_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_fungus", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:crimson_hyphae", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(92, 25, 29), }, ), ( "minecraft:crimson_nylium", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 31, 31), }, ), ( "minecraft:crimson_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_roots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(126, 8, 41), }, ), ( "minecraft:crimson_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( "minecraft:crimson_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 49, 70), }, ), ( "minecraft:crimson_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 50, 72), }, ), ( "minecraft:crimson_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:crying_obsidian", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(32, 10, 60), }, ), ( "minecraft:cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:cut_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:cut_red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:cut_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:cut_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:cyan_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cyan_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cyan_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cyan_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:cyan_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 137, 145), }, ), ( "minecraft:cyan_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 119, 136), }, ), ( "minecraft:cyan_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(36, 147, 157), }, ), ( "minecraft:cyan_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 118, 125), }, ), ( "minecraft:cyan_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 121, 135), }, ), ( "minecraft:cyan_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 127, 153), }, ), ( "minecraft:cyan_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 122, 147), }, ), ( "minecraft:cyan_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(86, 91, 91), }, ), ( "minecraft:cyan_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:cyan_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 137, 145), }, ), ( "minecraft:damaged_anvil", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( "minecraft:dandelion", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dark_oak_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dark_oak_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 51, 25), }, ), ( "minecraft:dark_oak_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(150, 150, 150), }, ), ( "minecraft:dark_oak_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(67, 45, 22), }, ), ( "minecraft:dark_oak_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(61, 90, 30), }, ), ( "minecraft:dark_oak_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( "minecraft:dark_oak_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 49, 23), }, ), ( "minecraft:dark_oak_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dark_oak_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(60, 46, 26), }, ), ( "minecraft:dark_prismarine", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( "minecraft:dark_prismarine_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( "minecraft:dark_prismarine_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( "minecraft:daylight_detector", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 116, 94), }, ), ( "minecraft:dead_brain_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_brain_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 117, 114), }, ), ( "minecraft:dead_brain_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_brain_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_bubble_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_bubble_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 123, 119), }, ), ( "minecraft:dead_bubble_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_bubble_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 78, 40), }, ), ( "minecraft:dead_fire_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_fire_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 123, 119), }, ), ( "minecraft:dead_fire_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_fire_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_horn_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_horn_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(133, 126, 122), }, ), ( "minecraft:dead_horn_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_horn_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_tube_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_tube_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 123, 119), }, ), ( "minecraft:dead_tube_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dead_tube_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:deepslate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 82), }, ), ( "minecraft:deepslate_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( "minecraft:deepslate_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( "minecraft:deepslate_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( "minecraft:deepslate_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( "minecraft:deepslate_coal_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 74, 76), }, ), ( "minecraft:deepslate_copper_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(92, 93, 89), }, ), ( "minecraft:deepslate_diamond_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(83, 106, 106), }, ), ( "minecraft:deepslate_emerald_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(78, 104, 87), }, ), ( "minecraft:deepslate_gold_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 102, 78), }, ), ( "minecraft:deepslate_iron_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 99, 94), }, ), ( "minecraft:deepslate_lapis_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 90, 115), }, ), ( "minecraft:deepslate_redstone_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(104, 73, 74), }, ), ( "minecraft:deepslate_tile_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( "minecraft:deepslate_tile_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( "minecraft:deepslate_tile_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( "minecraft:deepslate_tiles", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( "minecraft:detector_rail", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 104, 90), }, ), ( "minecraft:diamond_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(98, 237, 228), }, ), ( "minecraft:diamond_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 141, 140), }, ), ( "minecraft:diorite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( "minecraft:diorite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( "minecraft:diorite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( "minecraft:diorite_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( "minecraft:dirt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 96, 67), }, ), ( "minecraft:dirt_path", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 121, 65), }, ), ( "minecraft:dispenser", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( "minecraft:dragon_egg", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(12, 9, 15), }, ), ( "minecraft:dragon_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dragon_wall_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:dried_kelp_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(50, 58, 38), }, ), ( "minecraft:dripstone_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 107, 92), }, ), ( "minecraft:dropper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( "minecraft:emerald_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 203, 87), }, ), ( "minecraft:emerald_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 136, 115), }, ), ( "minecraft:enchanting_table", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(128, 75, 85), }, ), ( "minecraft:end_gateway", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( "minecraft:end_portal", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( "minecraft:end_portal_frame", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(91, 120, 97), }, ), ( "minecraft:end_rod", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:end_stone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(219, 222, 158), }, ), ( "minecraft:end_stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( "minecraft:end_stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( "minecraft:end_stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( "minecraft:end_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( "minecraft:ender_chest", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( "minecraft:exposed_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 125, 103), }, ), ( "minecraft:exposed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:exposed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:exposed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:farmland", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 44, 15), }, ), ( "minecraft:fern", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:fire", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(211, 140, 53), }, ), ( "minecraft:fire_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:fire_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 35, 46), }, ), ( "minecraft:fire_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:fire_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:fletching_table", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(197, 180, 133), }, ), ( "minecraft:flower_pot", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 68, 53), }, ), ( "minecraft:flowering_azalea", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 121, 64), }, ), ( "minecraft:flowering_azalea_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 111, 60), }, ), ( "minecraft:frosted_ice", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 181, 252), }, ), ( "minecraft:furnace", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( "minecraft:gilded_blackstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(55, 42, 38), }, ), ( "minecraft:glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 213, 219), }, ), ( "minecraft:glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(170, 210, 217), }, ), ( "minecraft:glow_item_frame", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:glow_lichen", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:glowstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 131, 84), }, ), ( "minecraft:gold_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 208, 61), }, ), ( "minecraft:gold_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(145, 133, 106), }, ), ( "minecraft:granite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( "minecraft:granite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( "minecraft:granite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( "minecraft:granite_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( "minecraft:grass", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:grass_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(147, 147, 147), }, ), ( "minecraft:grass_path", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 121, 65), }, ), ( "minecraft:gravel", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 127, 126), }, ), ( "minecraft:gray_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:gray_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:gray_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:gray_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:gray_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(62, 68, 71), }, ), ( "minecraft:gray_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 57, 61), }, ), ( "minecraft:gray_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 81, 84), }, ), ( "minecraft:gray_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(83, 90, 93), }, ), ( "minecraft:gray_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(55, 58, 62), }, ), ( "minecraft:gray_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 76, 76), }, ), ( "minecraft:gray_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 73, 73), }, ), ( "minecraft:gray_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 42, 35), }, ), ( "minecraft:gray_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:gray_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(62, 68, 71), }, ), ( "minecraft:green_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:green_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:green_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:green_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:green_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 109, 27), }, ), ( "minecraft:green_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 91, 36), }, ), ( "minecraft:green_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 119, 44), }, ), ( "minecraft:green_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 142, 67), }, ), ( "minecraft:green_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 100, 31), }, ), ( "minecraft:green_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 127, 51), }, ), ( "minecraft:green_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 122, 48), }, ), ( "minecraft:green_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 83, 42), }, ), ( "minecraft:green_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:green_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 109, 27), }, ), ( "minecraft:grindstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 142), }, ), ( "minecraft:hanging_roots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 115, 91), }, ), ( "minecraft:hay_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 139, 12), }, ), ( "minecraft:heavy_weighted_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 220, 220), }, ), ( "minecraft:honey_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(251, 185, 52), }, ), ( "minecraft:honeycomb_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(229, 148, 29), }, ), ( "minecraft:hopper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 74, 75), }, ), ( "minecraft:horn_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:horn_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 199, 66), }, ), ( "minecraft:horn_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:horn_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:ice", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(145, 183, 253), }, ), ( "minecraft:infested_chiseled_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 118, 119), }, ), ( "minecraft:infested_cobblestone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( "minecraft:infested_cracked_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 118), }, ), ( "minecraft:infested_deepslate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 82), }, ), ( "minecraft:infested_mossy_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( "minecraft:infested_stone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:infested_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( "minecraft:iron_bars", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 139, 135), }, ), ( "minecraft:iron_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 220, 220), }, ), ( "minecraft:iron_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(194, 193, 193), }, ), ( "minecraft:iron_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 129, 122), }, ), ( "minecraft:iron_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(202, 202, 202), }, ), ( "minecraft:item_frame", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:jack_o_lantern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(214, 152, 52), }, ), ( "minecraft:jigsaw", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 69, 81), }, ), ( "minecraft:jukebox", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 64, 47), }, ), ( "minecraft:jungle_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:jungle_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 119, 84), }, ), ( "minecraft:jungle_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(156, 154, 143), }, ), ( "minecraft:jungle_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 109, 70), }, ), ( "minecraft:jungle_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 81, 16), }, ), ( "minecraft:jungle_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( "minecraft:jungle_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(152, 110, 77), }, ), ( "minecraft:jungle_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:jungle_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 67, 25), }, ), ( "minecraft:kelp", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:kelp_plant", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(86, 130, 42), }, ), ( "minecraft:ladder", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lantern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 91, 83), }, ), ( "minecraft:lapis_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(30, 67, 140), }, ), ( "minecraft:lapis_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 117, 141), }, ), ( "minecraft:large_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:large_fern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:lava", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(212, 90, 18), }, ), ( "minecraft:lava_cauldron", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( "minecraft:lectern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(173, 137, 83), }, ), ( "minecraft:lever", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_blue_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_blue_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_blue_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_blue_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:light_blue_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 175, 217), }, ), ( "minecraft:light_blue_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(35, 137, 198), }, ), ( "minecraft:light_blue_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 180, 213), }, ), ( "minecraft:light_blue_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 164, 208), }, ), ( "minecraft:light_blue_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(49, 163, 212), }, ), ( "minecraft:light_blue_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 153, 216), }, ), ( "minecraft:light_blue_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 147, 208), }, ), ( "minecraft:light_blue_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(113, 108, 137), }, ), ( "minecraft:light_blue_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_blue_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 175, 217), }, ), ( "minecraft:light_gray_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_gray_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_gray_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_gray_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:light_gray_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 134), }, ), ( "minecraft:light_gray_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 115), }, ), ( "minecraft:light_gray_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 154, 148), }, ), ( "minecraft:light_gray_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(144, 166, 167), }, ), ( "minecraft:light_gray_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 124, 115), }, ), ( "minecraft:light_gray_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 153, 153), }, ), ( "minecraft:light_gray_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 147, 147), }, ), ( "minecraft:light_gray_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(135, 106, 97), }, ), ( "minecraft:light_gray_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:light_gray_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 134), }, ), ( "minecraft:light_weighted_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 208, 61), }, ), ( "minecraft:lightning_rod", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lilac", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 125, 147), }, ), ( "minecraft:lily_of_the_valley", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lily_pad", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(133, 133, 133), }, ), ( "minecraft:lime_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lime_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lime_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lime_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:lime_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 185, 25), }, ), ( "minecraft:lime_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 168, 24), }, ), ( "minecraft:lime_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 189, 41), }, ), ( "minecraft:lime_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 197, 55), }, ), ( "minecraft:lime_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 172, 23), }, ), ( "minecraft:lime_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 204, 25), }, ), ( "minecraft:lime_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 196, 24), }, ), ( "minecraft:lime_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 117, 52), }, ), ( "minecraft:lime_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:lime_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 185, 25), }, ), ( "minecraft:lodestone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 149, 152), }, ), ( "minecraft:loom", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 119, 91), }, ), ( "minecraft:magenta_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:magenta_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:magenta_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:magenta_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:magenta_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(189, 68, 179), }, ), ( "minecraft:magenta_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 48, 159), }, ), ( "minecraft:magenta_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 83, 184), }, ), ( "minecraft:magenta_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(208, 100, 191), }, ), ( "minecraft:magenta_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(173, 54, 163), }, ), ( "minecraft:magenta_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(178, 76, 216), }, ), ( "minecraft:magenta_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 73, 208), }, ), ( "minecraft:magenta_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 88, 108), }, ), ( "minecraft:magenta_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:magenta_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(189, 68, 179), }, ), ( "minecraft:magma_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 63, 31), }, ), ( "minecraft:medium_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:melon", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 144, 30), }, ), ( "minecraft:melon_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(153, 153, 153), }, ), ( "minecraft:moss_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 109, 45), }, ), ( "minecraft:moss_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 109, 45), }, ), ( "minecraft:mossy_cobblestone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( "minecraft:mossy_cobblestone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( "minecraft:mossy_cobblestone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( "minecraft:mossy_cobblestone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( "minecraft:mossy_stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( "minecraft:mossy_stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( "minecraft:mossy_stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( "minecraft:mossy_stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( "minecraft:moving_piston", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:mushroom_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(203, 196, 185), }, ), ( "minecraft:mycelium", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 98, 101), }, ), ( "minecraft:nether_brick_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( "minecraft:nether_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( "minecraft:nether_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( "minecraft:nether_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( "minecraft:nether_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( "minecraft:nether_gold_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 54, 42), }, ), ( "minecraft:nether_portal", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 11, 192), }, ), ( "minecraft:nether_quartz_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 65, 62), }, ), ( "minecraft:nether_sprouts", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(19, 151, 133), }, ), ( "minecraft:nether_wart", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 18, 19), }, ), ( "minecraft:nether_wart_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 2, 2), }, ), ( "minecraft:netherite_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 61, 63), }, ), ( "minecraft:netherrack", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 38, 38), }, ), ( "minecraft:note_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 58, 40), }, ), ( "minecraft:oak_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:oak_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 110, 66), }, ), ( "minecraft:oak_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Foliage}), + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(144, 144, 144), }, ), ( "minecraft:oak_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(151, 121, 73), }, ), ( "minecraft:oak_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 106, 40), }, ), ( "minecraft:oak_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:oak_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 99, 56), }, ), ( "minecraft:oak_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:oak_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 85, 50), }, ), ( "minecraft:observer", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(98, 98, 98), }, ), ( "minecraft:obsidian", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( "minecraft:orange_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:orange_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:orange_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:orange_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:orange_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 118, 19), }, ), ( "minecraft:orange_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(224, 97, 0), }, ), ( "minecraft:orange_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(227, 131, 31), }, ), ( "minecraft:orange_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 147, 91), }, ), ( "minecraft:orange_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 106, 8), }, ), ( "minecraft:orange_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 127, 51), }, ), ( "minecraft:orange_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(208, 122, 48), }, ), ( "minecraft:orange_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 83, 37), }, ), ( "minecraft:orange_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:orange_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:orange_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 118, 19), }, ), ( "minecraft:oxeye_daisy", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:oxidized_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(82, 162, 132), }, ), ( "minecraft:oxidized_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:oxidized_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:oxidized_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:packed_ice", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(141, 180, 250), }, ), ( "minecraft:peony", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 126, 139), }, ), ( "minecraft:petrified_oak_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:pink_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:pink_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:pink_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:pink_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:pink_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(237, 141, 172), }, ), ( "minecraft:pink_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(213, 101, 142), }, ), ( "minecraft:pink_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 153, 181), }, ), ( "minecraft:pink_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 154, 181), }, ), ( "minecraft:pink_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(230, 121, 157), }, ), ( "minecraft:pink_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(242, 127, 165), }, ), ( "minecraft:pink_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 122, 159), }, ), ( "minecraft:pink_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 78, 78), }, ), ( "minecraft:pink_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:pink_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:pink_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(237, 141, 172), }, ), ( "minecraft:piston", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 104, 96), }, ), ( "minecraft:piston_head", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 127, 87), }, ), ( "minecraft:player_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:player_wall_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:podzol", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(91, 63, 24), }, ), ( "minecraft:pointed_dripstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 102, 89), }, ), ( "minecraft:polished_andesite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( "minecraft:polished_andesite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( "minecraft:polished_andesite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( "minecraft:polished_basalt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 98, 100), }, ), ( "minecraft:polished_blackstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:polished_blackstone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( "minecraft:polished_blackstone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( "minecraft:polished_blackstone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( "minecraft:polished_blackstone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( "minecraft:polished_blackstone_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:polished_blackstone_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:polished_blackstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:polished_blackstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:polished_blackstone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( "minecraft:polished_deepslate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( "minecraft:polished_deepslate_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( "minecraft:polished_deepslate_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( "minecraft:polished_deepslate_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( "minecraft:polished_diorite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( "minecraft:polished_diorite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( "minecraft:polished_diorite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( "minecraft:polished_granite", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( "minecraft:polished_granite_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( "minecraft:polished_granite_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( "minecraft:poppy", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:potatoes", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 135, 47), }, ), ( "minecraft:potted_acacia_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 23), }, ), ( "minecraft:potted_allium", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 137, 183), }, ), ( "minecraft:potted_azalea_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 124, 47), }, ), ( "minecraft:potted_azure_bluet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 204, 127), }, ), ( "minecraft:potted_bamboo", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 144, 19), }, ), ( "minecraft:potted_birch_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 160, 79), }, ), ( "minecraft:potted_blue_orchid", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 162, 168), }, ), ( "minecraft:potted_brown_mushroom", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 116, 92), }, ), ( "minecraft:potted_cactus", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 127, 43), }, ), ( "minecraft:potted_cornflower", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 121, 146), }, ), ( "minecraft:potted_crimson_fungus", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(141, 44, 29), }, ), ( "minecraft:potted_crimson_roots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 8, 41), }, ), ( "minecraft:potted_dandelion", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 172, 43), }, ), ( "minecraft:potted_dark_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(61, 90, 30), }, ), ( "minecraft:potted_dead_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 78, 40), }, ), ( "minecraft:potted_fern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(124, 124, 124), }, ), ( "minecraft:potted_flowering_azalea_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 121, 64), }, ), ( "minecraft:potted_jungle_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 81, 16), }, ), ( "minecraft:potted_lily_of_the_valley", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 174, 95), }, ), ( "minecraft:potted_oak_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 106, 40), }, ), ( "minecraft:potted_orange_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 142, 30), }, ), ( "minecraft:potted_oxeye_daisy", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(179, 202, 143), }, ), ( "minecraft:potted_pink_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 157, 78), }, ), ( "minecraft:potted_poppy", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(128, 64, 37), }, ), ( "minecraft:potted_red_mushroom", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 75, 67), }, ), ( "minecraft:potted_red_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 128, 32), }, ), ( "minecraft:potted_spruce_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 60, 36), }, ), ( "minecraft:potted_warped_fungus", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 109, 87), }, ), ( "minecraft:potted_warped_roots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 136, 123), }, ), ( "minecraft:potted_white_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 164, 71), }, ), ( "minecraft:potted_wither_rose", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(41, 44, 23), }, ), ( "minecraft:powder_snow", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 253, 253), }, ), ( "minecraft:powder_snow_cauldron", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( "minecraft:powered_rail", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 109, 74), }, ), ( "minecraft:prismarine", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( "minecraft:prismarine_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( "minecraft:prismarine_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( "minecraft:prismarine_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( "minecraft:prismarine_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( "minecraft:prismarine_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( "minecraft:prismarine_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( "minecraft:pumpkin", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(198, 118, 24), }, ), ( "minecraft:pumpkin_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(154, 154, 154), }, ), ( "minecraft:purple_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:purple_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:purple_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:purple_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:purple_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 42, 172), }, ), ( "minecraft:purple_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(100, 31, 156), }, ), ( "minecraft:purple_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 55, 177), }, ), ( "minecraft:purple_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 48, 152), }, ), ( "minecraft:purple_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 32, 156), }, ), ( "minecraft:purple_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 63, 178), }, ), ( "minecraft:purple_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 61, 171), }, ), ( "minecraft:purple_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 70, 86), }, ), ( "minecraft:purple_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:purple_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 42, 172), }, ), ( "minecraft:purpur_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( "minecraft:purpur_pillar", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 129, 171), }, ), ( "minecraft:purpur_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( "minecraft:purpur_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( "minecraft:quartz_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:quartz_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 229, 221), }, ), ( "minecraft:quartz_pillar", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 230, 224), }, ), ( "minecraft:quartz_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:quartz_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:rail", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 111, 88), }, ), ( "minecraft:raw_copper_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 105, 79), }, ), ( "minecraft:raw_gold_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(221, 169, 46), }, ), ( "minecraft:raw_iron_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 135, 107), }, ), ( "minecraft:red_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:red_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 39, 34), }, ), ( "minecraft:red_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 32, 32), }, ), ( "minecraft:red_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 54, 50), }, ), ( "minecraft:red_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 59, 53), }, ), ( "minecraft:red_mushroom", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_mushroom_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(200, 46, 45), }, ), ( "minecraft:red_nether_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( "minecraft:red_nether_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( "minecraft:red_nether_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( "minecraft:red_nether_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( "minecraft:red_sand", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(190, 102, 33), }, ), ( "minecraft:red_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:red_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:red_sandstone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:red_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 31, 30), }, ), ( "minecraft:red_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 51, 51), }, ), ( "minecraft:red_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 48, 48), }, ), ( "minecraft:red_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(143, 61, 46), }, ), ( "minecraft:red_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:red_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 39, 34), }, ), ( "minecraft:redstone_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 24, 5), }, ), ( "minecraft:redstone_lamp", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(95, 54, 30), }, ), ( "minecraft:redstone_ore", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 109, 109), }, ), ( "minecraft:redstone_torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:redstone_wall_torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:redstone_wire", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 24, 5), }, ), ( "minecraft:repeater", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 157, 156), }, ), ( "minecraft:repeating_command_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 111, 176), }, ), ( "minecraft:respawn_anchor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 26, 144), }, ), ( "minecraft:rooted_dirt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(144, 103, 76), }, ), ( "minecraft:rose_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 66, 37), }, ), ( "minecraft:sand", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(219, 207, 163), }, ), ( "minecraft:sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:sandstone_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:scaffolding", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(174, 134, 80), }, ), ( "minecraft:sculk_sensor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(7, 70, 84), }, ), ( "minecraft:sea_lantern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(172, 199, 190), }, ), ( "minecraft:sea_pickle", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 97, 39), }, ), ( "minecraft:seagrass", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:shroomlight", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 146, 70), }, ), ( "minecraft:shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(139, 96, 139), }, ), ( "minecraft:sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:skeleton_skull", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:skeleton_wall_skull", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:slime_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 192, 91), }, ), ( "minecraft:small_amethyst_bud", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:small_dripleaf", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:smithing_table", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 58, 70), }, ), ( "minecraft:smoker", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 83, 81), }, ), ( "minecraft:smooth_basalt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 78), }, ), ( "minecraft:smooth_quartz", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:smooth_quartz_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:smooth_quartz_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( "minecraft:smooth_red_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:smooth_red_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:smooth_red_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( "minecraft:smooth_sandstone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:smooth_sandstone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:smooth_sandstone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( "minecraft:smooth_stone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 158, 158), }, ), ( "minecraft:smooth_stone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 158, 158), }, ), ( "minecraft:snow", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(249, 254, 254), }, ), ( "minecraft:snow_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(249, 254, 254), }, ), ( "minecraft:soul_campfire", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 204, 208), }, ), ( "minecraft:soul_fire", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 192, 197), }, ), ( "minecraft:soul_lantern", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(71, 99, 114), }, ), ( "minecraft:soul_sand", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 62, 50), }, ), ( "minecraft:soul_soil", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 57, 46), }, ), ( "minecraft:soul_torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:soul_wall_torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:spawner", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(36, 46, 62), }, ), ( "minecraft:sponge", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(195, 192, 74), }, ), ( "minecraft:spore_blossom", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(206, 96, 158), }, ), ( "minecraft:spruce_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:spruce_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 80, 48), }, ), ( "minecraft:spruce_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_leaves", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Spruce}), + flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), color: BlockColor(126, 126, 126), }, ), ( "minecraft:spruce_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 80, 46), }, ), ( "minecraft:spruce_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_sapling", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 60, 36), }, ), ( "minecraft:spruce_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( "minecraft:spruce_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 79, 47), }, ), ( "minecraft:spruce_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:spruce_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 37, 16), }, ), ( "minecraft:sticky_piston", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 104, 96), }, ), ( "minecraft:stone", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:stone_brick_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( "minecraft:stone_brick_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( "minecraft:stone_brick_wall", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( "minecraft:stone_bricks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( "minecraft:stone_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:stone_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:stone_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:stone_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( "minecraft:stonecutter", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 118, 111), }, ), ( "minecraft:stripped_acacia_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 91, 51), }, ), ( "minecraft:stripped_acacia_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(174, 92, 59), }, ), ( "minecraft:stripped_birch_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 171, 116), }, ), ( "minecraft:stripped_birch_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(196, 176, 118), }, ), ( "minecraft:stripped_crimson_hyphae", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 57, 90), }, ), ( "minecraft:stripped_crimson_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 56, 82), }, ), ( "minecraft:stripped_dark_oak_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(65, 44, 22), }, ), ( "minecraft:stripped_dark_oak_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 56, 36), }, ), ( "minecraft:stripped_jungle_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 122, 81), }, ), ( "minecraft:stripped_jungle_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 132, 84), }, ), ( "minecraft:stripped_oak_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 129, 77), }, ), ( "minecraft:stripped_oak_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(177, 144, 86), }, ), ( "minecraft:stripped_spruce_log", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(105, 80, 46), }, ), ( "minecraft:stripped_spruce_wood", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 89, 52), }, ), ( "minecraft:stripped_warped_hyphae", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 150, 147), }, ), ( "minecraft:stripped_warped_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 128, 124), }, ), ( "minecraft:structure_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 74, 90), }, ), ( "minecraft:structure_void", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:sugar_cane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 192, 101), }, ), ( "minecraft:sunflower", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 196, 54), }, ), ( "minecraft:sweet_berry_bush", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(68, 77, 50), }, ), ( "minecraft:tall_grass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(151, 149, 151), }, ), ( "minecraft:tall_seagrass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(59, 139, 14), }, ), ( "minecraft:target", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(226, 170, 157), }, ), ( "minecraft:terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(152, 94, 67), }, ), ( "minecraft:tinted_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 38, 46), }, ), ( "minecraft:tnt", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 62, 53), }, ), ( "minecraft:torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:trapped_chest", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( "minecraft:tripwire", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:tripwire_hook", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:tube_coral", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:tube_coral_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(49, 87, 206), }, ), ( "minecraft:tube_coral_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:tube_coral_wall_fan", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:tuff", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 109, 102), }, ), ( "minecraft:turtle_egg", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 226, 191), }, ), ( "minecraft:twisting_vines", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 143, 124), }, ), ( "minecraft:twisting_vines_plant", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 135, 122), }, ), ( "minecraft:vine", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Grass}), + flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(116, 116, 116), }, ), ( "minecraft:void_air", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:wall_torch", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:warped_button", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:warped_door", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 126, 120), }, ), ( "minecraft:warped_fence", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_fence_gate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_fungus", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:warped_hyphae", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 58, 77), }, ), ( "minecraft:warped_nylium", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 114, 101), }, ), ( "minecraft:warped_planks", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_pressure_plate", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_roots", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 138, 124), }, ), ( "minecraft:warped_sign", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( "minecraft:warped_stem", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 109, 110), }, ), ( "minecraft:warped_trapdoor", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 119, 111), }, ), ( "minecraft:warped_wall_sign", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:warped_wart_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(22, 119, 121), }, ), ( "minecraft:water", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque|Water}), + flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: BlockColor(177, 177, 177), }, ), ( "minecraft:water_cauldron", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( "minecraft:waxed_copper_block", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 107, 79), }, ), ( "minecraft:waxed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:waxed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:waxed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( "minecraft:waxed_exposed_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 125, 103), }, ), ( "minecraft:waxed_exposed_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:waxed_exposed_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:waxed_exposed_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( "minecraft:waxed_oxidized_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(82, 162, 132), }, ), ( "minecraft:waxed_oxidized_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:waxed_oxidized_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:waxed_oxidized_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( "minecraft:waxed_weathered_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 153, 110), }, ), ( "minecraft:waxed_weathered_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:waxed_weathered_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:waxed_weathered_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:weathered_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 153, 110), }, ), ( "minecraft:weathered_cut_copper", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:weathered_cut_copper_slab", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:weathered_cut_copper_stairs", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( "minecraft:weeping_vines", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(104, 1, 0), }, ), ( "minecraft:weeping_vines_plant", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 16, 12), }, ), ( "minecraft:wet_sponge", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 181, 70), }, ), ( "minecraft:wheat", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 151, 73), }, ), ( "minecraft:white_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:white_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:white_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:white_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:white_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 236, 236), }, ), ( "minecraft:white_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 213, 214), }, ), ( "minecraft:white_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(225, 227, 227), }, ), ( "minecraft:white_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 212, 202), }, ), ( "minecraft:white_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(215, 220, 221), }, ), ( "minecraft:white_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(255, 255, 255), }, ), ( "minecraft:white_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 246, 246), }, ), ( "minecraft:white_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(209, 178, 161), }, ), ( "minecraft:white_tulip", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:white_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:white_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 236, 236), }, ), ( "minecraft:wither_rose", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:wither_skeleton_skull", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:wither_skeleton_wall_skull", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:yellow_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:yellow_bed", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:yellow_candle", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:yellow_candle_cake", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( "minecraft:yellow_carpet", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 197, 39), }, ), ( "minecraft:yellow_concrete", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 175, 21), }, ), ( "minecraft:yellow_concrete_powder", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(232, 199, 54), }, ), ( "minecraft:yellow_glazed_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 192, 88), }, ), ( "minecraft:yellow_shulker_box", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 188, 29), }, ), ( "minecraft:yellow_stained_glass", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(229, 229, 51), }, ), ( "minecraft:yellow_stained_glass_pane", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(221, 221, 48), }, ), ( "minecraft:yellow_terracotta", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(186, 133, 35), }, ), ( "minecraft:yellow_wall_banner", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:yellow_wool", BlockType { - flags: make_bitflags!(BlockFlags::{Opaque}), + flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 197, 39), }, ), ( "minecraft:zombie_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( "minecraft:zombie_wall_head", BlockType { - flags: make_bitflags!(BlockFlags::{}), + flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 24549c3..d4a42a9 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -10,7 +10,7 @@ pub use legacy_block_types::LEGACY_BLOCK_TYPES; #[bitflags] #[repr(u8)] #[derive(Debug, Clone, Copy, PartialEq)] -pub enum BlockFlags { +pub enum BlockFlag { Opaque, Grass, Foliage, @@ -24,7 +24,7 @@ pub struct BlockColor(pub u8, pub u8, pub u8); #[derive(Debug, Clone, Copy)] pub struct BlockType { - pub flags: BitFlags, + pub flags: BitFlags, pub color: BlockColor, } From 2a941e5283a298478e39d6fe40cfb148140a0999 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 15 Feb 2023 00:19:08 +0100 Subject: [PATCH 081/460] resource: add BlockTypeMap type for convenience --- src/resource/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index d4a42a9..79020ba 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -28,7 +28,9 @@ pub struct BlockType { pub color: BlockColor, } -pub fn block_types() -> HashMap { +pub type BlockTypeMap = HashMap; + +pub fn block_types() -> BlockTypeMap { block_types::BLOCK_TYPES .iter() .map(|(k, v)| (String::from(*k), *v)) From 339e0b6a05d933fa4ddf7e28919b0d58d1bd74f4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 15 Feb 2023 00:20:15 +0100 Subject: [PATCH 082/460] resource: add BlockType::is() method to check for flags --- src/resource/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 79020ba..290dcce 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -28,6 +28,12 @@ pub struct BlockType { pub color: BlockColor, } +impl BlockType { + pub fn is(&self, flag: BlockFlag) -> bool { + self.flags.contains(flag) + } +} + pub type BlockTypeMap = HashMap; pub fn block_types() -> BlockTypeMap { From 921a218d561095d4d077c34edb8f276984f8605a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 15 Feb 2023 00:33:58 +0100 Subject: [PATCH 083/460] types: split BlockCoords into SectionBlockCoords and LayerBlockCoords --- src/types.rs | 28 ++++++++++++++++++++-------- src/world/section.rs | 8 ++++---- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/types.rs b/src/types.rs index 765ed39..39b106f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -39,15 +39,27 @@ coord_impl!(BlockY, BLOCKS_PER_CHUNK); pub struct BlockZ(pub u8); coord_impl!(BlockZ, BLOCKS_PER_CHUNK); -/// X, Y and Z coordinates of a block in a chunk section +/// X and Z coordinates of a block in a chunk #[derive(Clone, Copy, PartialEq, Eq)] -pub struct BlockCoords { +pub struct LayerBlockCoords { pub x: BlockX, - pub y: BlockY, pub z: BlockZ, } -impl BlockCoords { +impl Debug for LayerBlockCoords { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {})", self.x.0, self.z.0) + } +} + +/// X, Y and Z coordinates of a block in a chunk section +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct SectionBlockCoords { + pub xz: LayerBlockCoords, + pub y: BlockY, +} + +impl SectionBlockCoords { /// Computes a block's offset in various data structures /// /// Many chunk data structures store block and biome data in the same @@ -55,16 +67,16 @@ impl BlockCoords { /// for the block at a given coordinate is stored. pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; - let x = self.x.0 as usize; + let x = self.xz.x.0 as usize; let y = self.y.0 as usize; - let z = self.z.0 as usize; + let z = self.xz.z.0 as usize; ((y * N) + z) * N + x } } -impl Debug for BlockCoords { +impl Debug for SectionBlockCoords { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "({}, {}, {})", self.x.0, self.y.0, self.z.0) + write!(f, "({}, {}, {})", self.xz.x.0, self.y.0, self.xz.z.0) } } diff --git a/src/world/section.rs b/src/world/section.rs index e59daba..cee8b2a 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -24,7 +24,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { /// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section { - fn block_id_at(&self, coords: BlockCoords) -> Result<&str>; + fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str>; } /// Minecraft v1.18+ section biome data @@ -101,7 +101,7 @@ impl<'a> SectionV1_13<'a> { } /// Looks up the block type palette index at the given coordinates - fn palette_index_at(&self, coords: BlockCoords) -> usize { + fn palette_index_at(&self, coords: SectionBlockCoords) -> usize { let Some(block_states) = self.block_states else { return 0; }; @@ -133,7 +133,7 @@ impl<'a> SectionV1_13<'a> { } impl<'a> Section for SectionV1_13<'a> { - fn block_id_at(&self, coords: BlockCoords) -> Result<&str> { + fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str> { let index = self.palette_index_at(coords); let entry = self .palette @@ -167,7 +167,7 @@ impl<'a> SectionV0<'a> { } impl<'a> Section for SectionV0<'a> { - fn block_id_at(&self, coords: BlockCoords) -> Result<&str> { + fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str> { let offset = coords.offset(); let block = self.blocks[offset] as u8; From 789a4002c772320bad4a25ca85eac0dbf0eba43a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 15 Feb 2023 00:47:59 +0100 Subject: [PATCH 084/460] types: add Clone + Debug to ChunkArray iterators Added for consistency with LayerBlockArray. --- src/types.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types.rs b/src/types.rs index 39b106f..3a0bb22 100644 --- a/src/types.rs +++ b/src/types.rs @@ -116,15 +116,15 @@ impl Debug for ChunkCoords { pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { - pub fn keys() -> impl Iterator { + pub fn keys() -> impl Iterator + Clone + Debug { iproduct!(ChunkZ::iter(), ChunkX::iter()).map(|(z, x)| ChunkCoords { x, z }) } - pub fn values(&self) -> impl Iterator { + pub fn values(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| &self[k]) } - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| (k, &self[k])) } } From 3ef48783b7754a03284f47d34f2a4fc5ae7b5c5d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 15 Feb 2023 00:38:12 +0100 Subject: [PATCH 085/460] types: introduce LayerBlockArray A LayerBlockArray is a generic array of data stored for each block of a chunk layer. It provides the same methods as a ChunkArray. --- src/types.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/types.rs b/src/types.rs index 3a0bb22..a742977 100644 --- a/src/types.rs +++ b/src/types.rs @@ -52,6 +52,40 @@ impl Debug for LayerBlockCoords { } } +/// Generic array for data stored per block of a chunk layer +/// +/// Includes various convenient iteration functions. +#[derive(Debug, Clone, Copy, Default)] +pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); + +impl LayerBlockArray { + pub fn keys() -> impl Iterator + Clone + Debug { + iproduct!(BlockZ::iter(), BlockX::iter()).map(|(z, x)| LayerBlockCoords { x, z }) + } + + pub fn values(&self) -> impl Iterator + Clone + Debug { + Self::keys().map(|k| &self[k]) + } + + pub fn iter(&self) -> impl Iterator + Clone + Debug { + Self::keys().map(|k| (k, &self[k])) + } +} + +impl Index for LayerBlockArray { + type Output = T; + + fn index(&self, index: LayerBlockCoords) -> &Self::Output { + &self.0[index.z.0 as usize][index.x.0 as usize] + } +} + +impl IndexMut for LayerBlockArray { + fn index_mut(&mut self, index: LayerBlockCoords) -> &mut Self::Output { + &mut self.0[index.z.0 as usize][index.x.0 as usize] + } +} + /// X, Y and Z coordinates of a block in a chunk section #[derive(Clone, Copy, PartialEq, Eq)] pub struct SectionBlockCoords { From decb5c67a6016a794490fabeb20c38047c8d99bd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Feb 2023 10:55:28 +0100 Subject: [PATCH 086/460] world/section: to not use u128 type Getting the block index for unaligned blocks can be done just fine with only u64. --- src/world/section.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index cee8b2a..d02d1be 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -119,13 +119,11 @@ impl<'a> SectionV1_13<'a> { let bit_offset = offset * bits; let (word, bit_shift) = div_rem(bit_offset, 64); - if bit_shift + bits <= 64 { - block_states[word] as u64 >> bit_shift - } else { - let tmp = (block_states[word + 1] as u64 as u128) << 64 - | block_states[word] as u64 as u128; - (tmp >> bit_shift) as u64 + let mut tmp = (block_states[word] as u64) >> bit_shift; + if bit_shift + bits > 64 { + tmp |= (block_states[word + 1] as u64) << (64 - bit_shift); } + tmp }; (shifted & mask) as usize From 2530a557a90b5848b31c002d34a806f52adcb60d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Feb 2023 11:07:29 +0100 Subject: [PATCH 087/460] types: fix dangling doc reference --- src/types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.rs b/src/types.rs index a742977..a8c26e6 100644 --- a/src/types.rs +++ b/src/types.rs @@ -97,8 +97,8 @@ impl SectionBlockCoords { /// Computes a block's offset in various data structures /// /// Many chunk data structures store block and biome data in the same - /// order. [BlockCoords::offset] computes the offset at which the data - /// for the block at a given coordinate is stored. + /// order. This method computes the offset at which the data for the + /// block at a given coordinate is stored. pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let x = self.xz.x.0 as usize; From f48aa877d23f46c3f4b57e1ff145d580f717ff3a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Feb 2023 11:51:24 +0100 Subject: [PATCH 088/460] world: implement top_layer function Implement one of the core functions of MinedMap: finding the topmost visible block at each coordinate. --- src/main.rs | 19 ++++++- src/world/layer.rs | 130 +++++++++++++++++++++++++++++++++++++++++++++ src/world/mod.rs | 1 + 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 src/world/layer.rs diff --git a/src/main.rs b/src/main.rs index 2f104ed..63711c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; use anyhow::Result; use clap::Parser; +use minedmap::{resource, world}; + #[derive(Debug, Parser)] struct Args { /// Filename to dump @@ -12,9 +14,22 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); + let block_types = resource::block_types(); + minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( - |coords, value: minedmap::world::de::Chunk| { - println!("Chunk {:?}: {:#?}", coords, value); + |coords, data: world::de::Chunk| { + let chunk = match world::chunk::Chunk::new(&data) { + Ok(chunk) => chunk, + Err(err) => { + eprintln!("Chunk {:?}: {}", coords, err); + return; + } + }; + + match world::layer::top_layer(&chunk, &block_types) { + Ok(_) => {} + Err(err) => println!("{:?}", err), + } }, ) } diff --git a/src/world/layer.rs b/src/world/layer.rs new file mode 100644 index 0000000..d57c51f --- /dev/null +++ b/src/world/layer.rs @@ -0,0 +1,130 @@ +use anyhow::{Context, Result}; +use itertools::iproduct; + +use super::chunk::Chunk; +use crate::{ + resource::{BlockFlag, BlockType, BlockTypeMap}, + types::*, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BlockHeight(i32); + +impl BlockHeight { + /// Constructs a new [BlockHeight] from section and block Y indices + /// + /// Returns an error if the resulting coordindate does not fit into + /// an [i32]. + pub fn new(section: SectionY, block: BlockY) -> Result { + let height = section + .0 + .checked_mul(BLOCKS_PER_CHUNK as i32) + .and_then(|y| y.checked_add_unsigned(block.0.into())) + .context("Block height out of bounds")?; + Ok(BlockHeight(height)) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct BlockInfo { + block_type: BlockType, + y: BlockHeight, + depth: Option, +} + +/// Helper methods for [BlockInfo] +trait OptionBlockInfoExt { + /// Checks if a [BlockInfo] has been filled in completely + /// + /// Helper used by [top_layer] + fn done(&self) -> bool; + + /// Fills in a [BlockInfo] based on a [BlockType] + /// + /// Only fills in data if the block is part of the visible top layer + /// of the rendered map. + /// + /// Must be called on an incomplete [BlockInfo] entry. Returns `true` + /// if the entry has been filled in completely. + fn fill(&mut self, y: BlockHeight, block_type: BlockType) -> bool; +} + +impl OptionBlockInfoExt for Option { + fn done(&self) -> bool { + let Some(info) = self else { + return false; + }; + + info.depth.is_some() + } + + fn fill(&mut self, y: BlockHeight, block_type: BlockType) -> bool { + if !block_type.is(BlockFlag::Opaque) { + return false; + } + + if self.is_none() { + *self = Some(BlockInfo { + block_type, + y, + depth: None, + }); + } + + if block_type.is(BlockFlag::Water) { + return false; + } + + let info = self.as_mut().unwrap(); + info.depth = Some(y); + + true + } +} + +pub type BlockInfoArray = LayerBlockArray>; + +/// Fills in a [BlockInfoArray] with the information of the chunk's top +/// block layer +/// +/// For each (X, Z) coordinate pair, the topmost opaque block is +/// determined as the block that should be visible on the rendered +/// map. For water blocks, the height of the first non-water block +/// is additionally filled in as the water depth. +pub fn top_layer(chunk: &Chunk, block_types: &BlockTypeMap) -> Result { + use BLOCKS_PER_CHUNK as N; + + let mut done = 0; + let mut ret = BlockInfoArray::default(); + + for ((section_y, section), y, xz) in iproduct!( + chunk.sections().rev(), + BlockY::iter().rev(), + BlockInfoArray::keys() + ) { + let entry = &mut ret[xz]; + if entry.done() { + continue; + } + + let coords = SectionBlockCoords { xz, y }; + let block_id = section.block_id_at(coords)?; + let Some(&block_type) = block_types.get(block_id) else { + eprintln!("Unknown block type: {}", block_id); + continue; + }; + let height = BlockHeight::new(section_y, y)?; + if !entry.fill(height, block_type) { + continue; + } + + assert!(entry.done()); + + done += 1; + if done == N * N { + break; + } + } + + Ok(ret) +} diff --git a/src/world/mod.rs b/src/world/mod.rs index ae071e0..9879066 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,3 +1,4 @@ pub mod chunk; pub mod de; +pub mod layer; pub mod section; From f3a671145851de11ab3dac802012aa7399dee037 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Feb 2023 13:30:58 +0100 Subject: [PATCH 089/460] Update dependencies --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3efed67..7d96fbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.4" +version = "4.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" dependencies = [ "bitflags", "clap_derive", @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" dependencies = [ "os_str_bytes", ] @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" dependencies = [ "hermit-abi", "io-lifetimes", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "os_str_bytes" @@ -374,9 +374,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", From 2d0f2fb8651de1507f5221d74a2ca68819b83f3c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Feb 2023 17:46:00 +0100 Subject: [PATCH 090/460] main: iterate over regions of a Minecraft save dir --- src/main.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 63711c1..c10cd4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,42 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; -use anyhow::Result; +use anyhow::{Context, Result}; use clap::Parser; use minedmap::{resource, world}; #[derive(Debug, Parser)] struct Args { - /// Filename to dump - file: PathBuf, + /// Minecraft save directory + savedir: PathBuf, } -fn main() -> Result<()> { - let args = Args::parse(); +/// Type with methods for processing the regions of a Minecraft save directory +struct RegionProcessor { + block_types: resource::BlockTypeMap, +} - let block_types = resource::block_types(); +impl RegionProcessor { + fn new() -> Self { + RegionProcessor { + block_types: resource::block_types(), + } + } - minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( - |coords, data: world::de::Chunk| { + /// Parses a filename in the format r.X.Z.mca into the contained X and Z values + fn parse_region_filename(path: &Path) -> Option<(i32, i32)> { + let file_name = path.file_name()?.to_str()?; + let parts: Vec<_> = file_name.split('.').collect(); + let &["r", x, z, "mca"] = parts.as_slice() else { + return None; + }; + + Some((x.parse().ok()?, z.parse().ok()?)) + } + + /// Processes a single region file + fn process_region(&self, path: &Path, _x: i32, _z: i32) -> Result<()> { + minedmap::io::region::from_file(path)?.foreach_chunk(|coords, data: world::de::Chunk| { let chunk = match world::chunk::Chunk::new(&data) { Ok(chunk) => chunk, Err(err) => { @@ -26,10 +45,47 @@ fn main() -> Result<()> { } }; - match world::layer::top_layer(&chunk, &block_types) { + match world::layer::top_layer(&chunk, &self.block_types) { Ok(_) => {} Err(err) => println!("{:?}", err), } - }, - ) + }) + } + + /// Iterates over all region files of a Minecraft save directory + fn process_region_dir(&self, regiondir: &Path) -> Result<()> { + let read_dir = regiondir + .read_dir() + .with_context(|| format!("Failed to read directory {}", regiondir.display()))?; + + for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { + // We are only interested in regular files + entry + .file_type() + .map(|file_type| file_type.is_file()) + .unwrap_or_default() + }) { + let path = entry.path(); + let Some((x, z)) = Self::parse_region_filename(&path) else { + continue; + }; + + if let Err(err) = self.process_region(&path, x, z) { + eprintln!("Failed to process region r.{}.{}.mca: {}", x, z, err); + } + } + + Ok(()) + } +} + +fn main() -> Result<()> { + let args = Args::parse(); + + let regiondir: PathBuf = [&args.savedir, Path::new("region")].iter().collect(); + + let region_processor = RegionProcessor::new(); + region_processor.process_region_dir(®iondir)?; + + Ok(()) } From 551056803d45a7f152307f9592e1719b7a85c7c4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Feb 2023 23:23:00 +0100 Subject: [PATCH 091/460] Add Serialize/Deserialize impls to various types We want to be able to store this data to disk temporarily. --- src/resource/mod.rs | 23 +++++++++++++++++++++-- src/types.rs | 5 +++-- src/world/layer.rs | 5 +++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 290dcce..7f3a499 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -6,6 +6,7 @@ use std::collections::HashMap; use enumflags2::{bitflags, BitFlags}; pub use legacy_block_types::LEGACY_BLOCK_TYPES; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[bitflags] #[repr(u8)] @@ -19,11 +20,29 @@ pub enum BlockFlag { Water, } -#[derive(Debug, Clone, Copy)] +fn serialize_block_flags(flags: &BitFlags, serializer: S) -> Result +where + S: Serializer, +{ + flags.bits().serialize(serializer) +} +fn deserialize_block_flags<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let bits = u8::deserialize(deserializer)?; + BitFlags::::from_bits(bits).map_err(de::Error::custom) +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockColor(pub u8, pub u8, pub u8); -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockType { + #[serde( + serialize_with = "serialize_block_flags", + deserialize_with = "deserialize_block_flags" + )] pub flags: BitFlags, pub color: BlockColor, } diff --git a/src/types.rs b/src/types.rs index a8c26e6..2598485 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,6 +5,7 @@ use std::{ }; use itertools::iproduct; +use serde::{Deserialize, Serialize}; macro_rules! coord_impl { ($t:ident, $max:expr) => { @@ -55,7 +56,7 @@ impl Debug for LayerBlockCoords { /// Generic array for data stored per block of a chunk layer /// /// Includes various convenient iteration functions. -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); impl LayerBlockArray { @@ -146,7 +147,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)] +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { diff --git a/src/world/layer.rs b/src/world/layer.rs index d57c51f..16260c4 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Result}; use itertools::iproduct; +use serde::{Deserialize, Serialize}; use super::chunk::Chunk; use crate::{ @@ -7,7 +8,7 @@ use crate::{ types::*, }; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct BlockHeight(i32); impl BlockHeight { @@ -25,7 +26,7 @@ impl BlockHeight { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockInfo { block_type: BlockType, y: BlockHeight, From b2d849081d42b61d772a8c06f75666b4acfef9f8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Feb 2023 01:01:37 +0100 Subject: [PATCH 092/460] io/region: allow stopping foreach_chunk early Errors returned from the callback stop the loop early. --- src/bin/regiondump.rs | 1 + src/io/region.rs | 4 ++-- src/main.rs | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 5663a80..f3b7210 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -15,6 +15,7 @@ fn main() -> Result<()> { minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( |coords, value: fastnbt::Value| { println!("Chunk {:?}: {:#x?}", coords, value); + Ok(()) }, ) } diff --git a/src/io/region.rs b/src/io/region.rs index 93ff42b..e5c2528 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -73,7 +73,7 @@ impl Region { where R: Read + Seek, T: DeserializeOwned, - F: FnMut(ChunkCoords, T), + F: FnMut(ChunkCoords, T) -> Result<()>, { let Region { mut reader } = self; @@ -119,7 +119,7 @@ impl Region { let chunk = decode_chunk(&buffer) .with_context(|| format!("Failed to decode data for chunk {:?}", coords))?; - f(coords, chunk); + f(coords, chunk)?; } Ok(()) diff --git a/src/main.rs b/src/main.rs index c10cd4a..32aca9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,14 +41,15 @@ impl RegionProcessor { Ok(chunk) => chunk, Err(err) => { eprintln!("Chunk {:?}: {}", coords, err); - return; + return Ok(()); } }; match world::layer::top_layer(&chunk, &self.block_types) { Ok(_) => {} Err(err) => println!("{:?}", err), - } + }; + Ok(()) }) } From fd0c9fbf1b82dd6dcfb730c929ec049cbc3e7b84 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Feb 2023 01:11:59 +0100 Subject: [PATCH 093/460] main: improve process_region() error handling --- src/main.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 32aca9a..7b9e573 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,19 +37,14 @@ impl RegionProcessor { /// Processes a single region file fn process_region(&self, path: &Path, _x: i32, _z: i32) -> Result<()> { minedmap::io::region::from_file(path)?.foreach_chunk(|coords, data: world::de::Chunk| { - let chunk = match world::chunk::Chunk::new(&data) { - Ok(chunk) => chunk, - Err(err) => { - eprintln!("Chunk {:?}: {}", coords, err); - return Ok(()); - } - }; + (|| -> Result<()> { + let chunk = world::chunk::Chunk::new(&data)?; - match world::layer::top_layer(&chunk, &self.block_types) { - Ok(_) => {} - Err(err) => println!("{:?}", err), - }; - Ok(()) + let _top_layer = world::layer::top_layer(&chunk, &self.block_types)?; + + Ok(()) + })() + .with_context(|| format!("Failed to process chunk {:?}", coords)) }) } From f47b38b2ca48b310faeb650fb5ff39181d5a4590 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 26 Feb 2023 13:29:04 +0100 Subject: [PATCH 094/460] world/layer: return boxed BlockInfoArray from top_layer() Avoid copying around large structures, and allow creating arrays of BlockInfoArrays without overflowing the stack. --- src/world/layer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index 16260c4..f8a7302 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -92,11 +92,11 @@ pub type BlockInfoArray = LayerBlockArray>; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk, block_types: &BlockTypeMap) -> Result { +pub fn top_layer(chunk: &Chunk, block_types: &BlockTypeMap) -> Result> { use BLOCKS_PER_CHUNK as N; let mut done = 0; - let mut ret = BlockInfoArray::default(); + let mut ret = Box::::default(); for ((section_y, section), y, xz) in iproduct!( chunk.sections().rev(), From 21fd3a42ca29f7d6b1124799db1b79c34993a8c9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Feb 2023 00:44:49 +0100 Subject: [PATCH 095/460] io: add storage helper Use bincode+zstd to serialize data structures for temporary storage. --- Cargo.lock | 59 +++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/io/mod.rs | 1 + src/io/storage.rs | 22 ++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 src/io/storage.rs diff --git a/Cargo.lock b/Cargo.lock index 7d96fbc..5adcd72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -43,6 +52,9 @@ name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] [[package]] name = "cesu8" @@ -214,6 +226,15 @@ dependencies = [ "either", ] +[[package]] +name = "jobserver" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] + [[package]] name = "libc" version = "0.2.139" @@ -231,6 +252,7 @@ name = "minedmap" version = "0.1.0" dependencies = [ "anyhow", + "bincode", "bytemuck", "clap", "enumflags2", @@ -239,6 +261,7 @@ dependencies = [ "itertools", "num-integer", "serde", + "zstd", ] [[package]] @@ -281,6 +304,12 @@ version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -500,3 +529,33 @@ name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "zstd" +version = "0.12.3+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.4+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.7+zstd.1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index b5ef027..6f40d32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ default-run = "minedmap" [dependencies] anyhow = "1.0.68" +bincode = "1.3.3" bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } enumflags2 = "0.7.5" @@ -17,3 +18,4 @@ flate2 = "1.0.25" itertools = "0.10.5" num-integer = "0.1.45" serde = "1.0.152" +zstd = "0.12.3" diff --git a/src/io/mod.rs b/src/io/mod.rs index f109d15..4098f3b 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,2 +1,3 @@ pub mod data; pub mod region; +pub mod storage; diff --git a/src/io/storage.rs b/src/io/storage.rs new file mode 100644 index 0000000..86430b3 --- /dev/null +++ b/src/io/storage.rs @@ -0,0 +1,22 @@ +use std::{ + fs::File, + io::{BufWriter, Write}, + path::Path, +}; + +use anyhow::{Context, Result}; +use serde::Serialize; + +pub fn write(path: &Path, value: &T) -> Result<()> { + (|| -> Result<()> { + let file = File::create(path)?; + let writer = BufWriter::new(file); + let mut compressor = zstd::Encoder::new(writer, 1)?; + bincode::serialize_into(&mut compressor, value)?; + let writer = compressor.finish()?; + let mut file = writer.into_inner()?; + file.flush()?; + Ok(()) + })() + .with_context(|| format!("Failed to write file {}", path.display())) +} From 768ab13205565ba1921bac0d0b190571870550ed Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Feb 2023 23:54:21 +0100 Subject: [PATCH 096/460] main: rename savedir argument to input_dir --- src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7b9e573..03a10dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use minedmap::{resource, world}; #[derive(Debug, Parser)] struct Args { /// Minecraft save directory - savedir: PathBuf, + input_dir: PathBuf, } /// Type with methods for processing the regions of a Minecraft save directory @@ -78,7 +78,7 @@ impl RegionProcessor { fn main() -> Result<()> { let args = Args::parse(); - let regiondir: PathBuf = [&args.savedir, Path::new("region")].iter().collect(); + let regiondir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); let region_processor = RegionProcessor::new(); region_processor.process_region_dir(®iondir)?; From b68f04496c8c51e6ad9e89e8e5b24f3a2b7b4ce3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Feb 2023 23:57:48 +0100 Subject: [PATCH 097/460] main: introduce RegionCoords type alias --- src/main.rs | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 03a10dc..243c615 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,8 @@ struct Args { input_dir: PathBuf, } +type RegionCoords = (i32, i32); + /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor { block_types: resource::BlockTypeMap, @@ -24,7 +26,7 @@ impl RegionProcessor { } /// Parses a filename in the format r.X.Z.mca into the contained X and Z values - fn parse_region_filename(path: &Path) -> Option<(i32, i32)> { + fn parse_region_filename(path: &Path) -> Option { let file_name = path.file_name()?.to_str()?; let parts: Vec<_> = file_name.split('.').collect(); let &["r", x, z, "mca"] = parts.as_slice() else { @@ -35,17 +37,19 @@ impl RegionProcessor { } /// Processes a single region file - fn process_region(&self, path: &Path, _x: i32, _z: i32) -> Result<()> { - minedmap::io::region::from_file(path)?.foreach_chunk(|coords, data: world::de::Chunk| { - (|| -> Result<()> { - let chunk = world::chunk::Chunk::new(&data)?; + fn process_region(&self, path: &Path, _coords: RegionCoords) -> Result<()> { + minedmap::io::region::from_file(path)?.foreach_chunk( + |chunk_coords, data: world::de::Chunk| { + (|| -> Result<()> { + let chunk = world::chunk::Chunk::new(&data)?; - let _top_layer = world::layer::top_layer(&chunk, &self.block_types)?; + let _top_layer = world::layer::top_layer(&chunk, &self.block_types)?; - Ok(()) - })() - .with_context(|| format!("Failed to process chunk {:?}", coords)) - }) + Ok(()) + })() + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords)) + }, + ) } /// Iterates over all region files of a Minecraft save directory @@ -62,12 +66,15 @@ impl RegionProcessor { .unwrap_or_default() }) { let path = entry.path(); - let Some((x, z)) = Self::parse_region_filename(&path) else { + let Some(coords) = Self::parse_region_filename(&path) else { continue; }; - if let Err(err) = self.process_region(&path, x, z) { - eprintln!("Failed to process region r.{}.{}.mca: {}", x, z, err); + if let Err(err) = self.process_region(&path, coords) { + eprintln!( + "Failed to process region r.{}.{}.mca: {}", + coords.0, coords.1, err, + ); } } From 04ab8c321f5035d44283ade2837f67fecff91382 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:00:40 +0100 Subject: [PATCH 098/460] main: fix formatting rustfmt still doesn't handle let-else... --- src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 243c615..17c3898 100644 --- a/src/main.rs +++ b/src/main.rs @@ -67,8 +67,8 @@ impl RegionProcessor { }) { let path = entry.path(); let Some(coords) = Self::parse_region_filename(&path) else { - continue; - }; + continue; + }; if let Err(err) = self.process_region(&path, coords) { eprintln!( From 447a9482fe2c1090403af01d5546b262404620c6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:02:23 +0100 Subject: [PATCH 099/460] main: create output directory for processed data files --- src/main.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 17c3898..cdca041 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + fs, + path::{Path, PathBuf}, +}; use anyhow::{Context, Result}; use clap::Parser; @@ -9,6 +12,8 @@ use minedmap::{resource, world}; struct Args { /// Minecraft save directory input_dir: PathBuf, + /// MinedMap data directory + output_dir: PathBuf, } type RegionCoords = (i32, i32); @@ -16,12 +21,14 @@ type RegionCoords = (i32, i32); /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor { block_types: resource::BlockTypeMap, + processed_dir: PathBuf, } impl RegionProcessor { - fn new() -> Self { + fn new(output_dir: &Path) -> Self { RegionProcessor { block_types: resource::block_types(), + processed_dir: [output_dir, Path::new("processed")].iter().collect(), } } @@ -58,6 +65,13 @@ impl RegionProcessor { .read_dir() .with_context(|| format!("Failed to read directory {}", regiondir.display()))?; + fs::create_dir_all(&self.processed_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.processed_dir.display(), + ) + })?; + for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { // We are only interested in regular files entry @@ -87,7 +101,7 @@ fn main() -> Result<()> { let regiondir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); - let region_processor = RegionProcessor::new(); + let region_processor = RegionProcessor::new(&args.output_dir); region_processor.process_region_dir(®iondir)?; Ok(()) From d77dcce77801b4ac66f02cc04713f2dd6277ce4f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:02:47 +0100 Subject: [PATCH 100/460] main: print message when processing region --- src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index cdca041..10e9445 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,9 @@ impl RegionProcessor { } /// Processes a single region file - fn process_region(&self, path: &Path, _coords: RegionCoords) -> Result<()> { + fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { + println!("Processing region r.{}.{}.mca", coords.0, coords.1); + minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { (|| -> Result<()> { From 18cecb947e95cb2279b238db188a48e907d0b31e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:09:11 +0100 Subject: [PATCH 101/460] main: factor out process_chunk() method --- src/main.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 10e9445..9d08dba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,20 +43,22 @@ impl RegionProcessor { Some((x.parse().ok()?, z.parse().ok()?)) } + /// Processes a single chunk + fn process_chunk(&self, data: world::de::Chunk) -> Result> { + let chunk = world::chunk::Chunk::new(&data)?; + world::layer::top_layer(&chunk, &self.block_types) + } + /// Processes a single region file fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { println!("Processing region r.{}.{}.mca", coords.0, coords.1); minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - (|| -> Result<()> { - let chunk = world::chunk::Chunk::new(&data)?; - - let _top_layer = world::layer::top_layer(&chunk, &self.block_types)?; - - Ok(()) - })() - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords)) + let _processed_chunk = self + .process_chunk(data) + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))?; + Ok(()) }, ) } From e02a1fc0c986eca9d3db6fbbab0e9d0c85511c74 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:11:42 +0100 Subject: [PATCH 102/460] main: collect processed chunks in array --- src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9d08dba..8ba8efc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::{ use anyhow::{Context, Result}; use clap::Parser; -use minedmap::{resource, world}; +use minedmap::{resource, types::*, world}; #[derive(Debug, Parser)] struct Args { @@ -53,11 +53,15 @@ impl RegionProcessor { fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { println!("Processing region r.{}.{}.mca", coords.0, coords.1); + let mut processed_data: ChunkArray>> = + Default::default(); + minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let _processed_chunk = self + let processed_chunk = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))?; + processed_data[chunk_coords] = Some(processed_chunk); Ok(()) }, ) From 194715ad09e59c3c58eab42882669b9afc355eac Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 00:13:06 +0100 Subject: [PATCH 103/460] main: store processed region data --- src/main.rs | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8ba8efc..76cebde 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::{ use anyhow::{Context, Result}; use clap::Parser; -use minedmap::{resource, types::*, world}; +use minedmap::{io::storage, resource, types::*, world}; #[derive(Debug, Parser)] struct Args { @@ -43,12 +43,42 @@ impl RegionProcessor { Some((x.parse().ok()?, z.parse().ok()?)) } + fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.bin{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.processed_dir, Path::new(&filename)].iter().collect() + } + /// Processes a single chunk fn process_chunk(&self, data: world::de::Chunk) -> Result> { let chunk = world::chunk::Chunk::new(&data)?; world::layer::top_layer(&chunk, &self.block_types) } + fn save_region( + &self, + region: RegionCoords, + processed_data: &ChunkArray>>, + ) -> Result<()> { + let tmp_path = self.processed_path(region, true); + storage::write(&tmp_path, processed_data)?; + + let output_path = self.processed_path(region, false); + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; + + Ok(()) + } + /// Processes a single region file fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { println!("Processing region r.{}.{}.mca", coords.0, coords.1); @@ -64,7 +94,11 @@ impl RegionProcessor { processed_data[chunk_coords] = Some(processed_chunk); Ok(()) }, - ) + )?; + + self.save_region(coords, &processed_data)?; + + Ok(()) } /// Iterates over all region files of a Minecraft save directory From ca6afa0cf981b2c36632ca6e621612b8b9be5676 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 19:16:09 +0100 Subject: [PATCH 104/460] main: return list of region coordinates from process_region_dir() --- src/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 76cebde..cf1f003 100644 --- a/src/main.rs +++ b/src/main.rs @@ -102,7 +102,9 @@ impl RegionProcessor { } /// Iterates over all region files of a Minecraft save directory - fn process_region_dir(&self, regiondir: &Path) -> Result<()> { + /// + /// Returns a list of the coordinates of all processed regions + fn process_region_dir(&self, regiondir: &Path) -> Result> { let read_dir = regiondir .read_dir() .with_context(|| format!("Failed to read directory {}", regiondir.display()))?; @@ -114,6 +116,8 @@ impl RegionProcessor { ) })?; + let mut ret = Vec::new(); + for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { // We are only interested in regular files entry @@ -132,9 +136,11 @@ impl RegionProcessor { coords.0, coords.1, err, ); } + + ret.push(coords); } - Ok(()) + Ok(ret) } } From ea604b88f20044212c6b1a61e5e766ec0efa675a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 19:17:04 +0100 Subject: [PATCH 105/460] main: rename regiondir variable to region_dir For consistency with other _dir variables. --- src/main.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index cf1f003..23f6609 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,10 +104,10 @@ impl RegionProcessor { /// Iterates over all region files of a Minecraft save directory /// /// Returns a list of the coordinates of all processed regions - fn process_region_dir(&self, regiondir: &Path) -> Result> { - let read_dir = regiondir + fn process_region_dir(&self, region_dir: &Path) -> Result> { + let read_dir = region_dir .read_dir() - .with_context(|| format!("Failed to read directory {}", regiondir.display()))?; + .with_context(|| format!("Failed to read directory {}", region_dir.display()))?; fs::create_dir_all(&self.processed_dir).with_context(|| { format!( @@ -147,10 +147,10 @@ impl RegionProcessor { fn main() -> Result<()> { let args = Args::parse(); - let regiondir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); + let region_dir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); let region_processor = RegionProcessor::new(&args.output_dir); - region_processor.process_region_dir(®iondir)?; + region_processor.process_region_dir(®ion_dir)?; Ok(()) } From a2ba7e4738d14339696f092a25f9bb8f556188c9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 19:17:50 +0100 Subject: [PATCH 106/460] main: build processed_dir path outside of RegionProcessor::new() --- src/main.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 23f6609..841c177 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,16 +19,16 @@ struct Args { type RegionCoords = (i32, i32); /// Type with methods for processing the regions of a Minecraft save directory -struct RegionProcessor { +struct RegionProcessor<'a> { block_types: resource::BlockTypeMap, - processed_dir: PathBuf, + processed_dir: &'a Path, } -impl RegionProcessor { - fn new(output_dir: &Path) -> Self { +impl<'a> RegionProcessor<'a> { + fn new(processed_dir: &'a Path) -> Self { RegionProcessor { block_types: resource::block_types(), - processed_dir: [output_dir, Path::new("processed")].iter().collect(), + processed_dir, } } @@ -148,8 +148,9 @@ fn main() -> Result<()> { let args = Args::parse(); let region_dir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); + let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); - let region_processor = RegionProcessor::new(&args.output_dir); + let region_processor = RegionProcessor::new(&processed_dir); region_processor.process_region_dir(®ion_dir)?; Ok(()) From c5ca1d9821196929ece96f4ad6acf3696f1d1d4f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 19:27:09 +0100 Subject: [PATCH 107/460] main: pass region_dir to RegionProcessor::new(), consume when processing --- src/main.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 841c177..32c2659 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,13 +21,15 @@ type RegionCoords = (i32, i32); /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { block_types: resource::BlockTypeMap, + region_dir: &'a Path, processed_dir: &'a Path, } impl<'a> RegionProcessor<'a> { - fn new(processed_dir: &'a Path) -> Self { + fn new(region_dir: &'a Path, processed_dir: &'a Path) -> Self { RegionProcessor { block_types: resource::block_types(), + region_dir, processed_dir, } } @@ -104,10 +106,11 @@ impl<'a> RegionProcessor<'a> { /// Iterates over all region files of a Minecraft save directory /// /// Returns a list of the coordinates of all processed regions - fn process_region_dir(&self, region_dir: &Path) -> Result> { - let read_dir = region_dir + fn run(self) -> Result> { + let read_dir = self + .region_dir .read_dir() - .with_context(|| format!("Failed to read directory {}", region_dir.display()))?; + .with_context(|| format!("Failed to read directory {}", self.region_dir.display()))?; fs::create_dir_all(&self.processed_dir).with_context(|| { format!( @@ -150,8 +153,7 @@ fn main() -> Result<()> { let region_dir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); - let region_processor = RegionProcessor::new(&processed_dir); - region_processor.process_region_dir(®ion_dir)?; + RegionProcessor::new(®ion_dir, &processed_dir).run()?; Ok(()) } From 73b13c1afb124ba97a7bca39379cd08053186640 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 21:01:25 +0100 Subject: [PATCH 108/460] main: move path handling to separate struct --- src/main.rs | 69 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 32c2659..9183ad7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,19 +18,44 @@ struct Args { type RegionCoords = (i32, i32); +struct Paths { + region_dir: PathBuf, + processed_dir: PathBuf, +} + +impl Paths { + fn new(args: Args) -> Self { + let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); + let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + + Paths { + region_dir, + processed_dir, + } + } + + fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.bin{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.processed_dir, Path::new(&filename)].iter().collect() + } +} + /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { block_types: resource::BlockTypeMap, - region_dir: &'a Path, - processed_dir: &'a Path, + paths: &'a Paths, } impl<'a> RegionProcessor<'a> { - fn new(region_dir: &'a Path, processed_dir: &'a Path) -> Self { + fn new(paths: &'a Paths) -> Self { RegionProcessor { block_types: resource::block_types(), - region_dir, - processed_dir, + paths, } } @@ -45,16 +70,6 @@ impl<'a> RegionProcessor<'a> { Some((x.parse().ok()?, z.parse().ok()?)) } - fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.bin{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); - [&self.processed_dir, Path::new(&filename)].iter().collect() - } - /// Processes a single chunk fn process_chunk(&self, data: world::de::Chunk) -> Result> { let chunk = world::chunk::Chunk::new(&data)?; @@ -66,10 +81,10 @@ impl<'a> RegionProcessor<'a> { region: RegionCoords, processed_data: &ChunkArray>>, ) -> Result<()> { - let tmp_path = self.processed_path(region, true); + let tmp_path = self.paths.processed_path(region, true); storage::write(&tmp_path, processed_data)?; - let output_path = self.processed_path(region, false); + let output_path = self.paths.processed_path(region, false); fs::rename(&tmp_path, &output_path).with_context(|| { format!( "Failed to rename {} to {}", @@ -107,15 +122,17 @@ impl<'a> RegionProcessor<'a> { /// /// Returns a list of the coordinates of all processed regions fn run(self) -> Result> { - let read_dir = self - .region_dir - .read_dir() - .with_context(|| format!("Failed to read directory {}", self.region_dir.display()))?; + let read_dir = self.paths.region_dir.read_dir().with_context(|| { + format!( + "Failed to read directory {}", + self.paths.region_dir.display() + ) + })?; - fs::create_dir_all(&self.processed_dir).with_context(|| { + fs::create_dir_all(&self.paths.processed_dir).with_context(|| { format!( "Failed to create directory {}", - self.processed_dir.display(), + self.paths.processed_dir.display(), ) })?; @@ -149,11 +166,9 @@ impl<'a> RegionProcessor<'a> { fn main() -> Result<()> { let args = Args::parse(); + let paths = Paths::new(args); - let region_dir: PathBuf = [&args.input_dir, Path::new("region")].iter().collect(); - let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect(); - - RegionProcessor::new(®ion_dir, &processed_dir).run()?; + RegionProcessor::new(&paths).run()?; Ok(()) } From 0673c89bd8109a3695d4930ff837b4e00a6fe0be Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 21:45:05 +0100 Subject: [PATCH 109/460] main: add stub tile renderer struct This only prints messages so far. --- src/main.rs | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 9183ad7..30b3b18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,16 +21,19 @@ type RegionCoords = (i32, i32); struct Paths { region_dir: PathBuf, processed_dir: PathBuf, + map_dir: PathBuf, } impl Paths { fn new(args: Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); Paths { region_dir, processed_dir, + map_dir, } } @@ -164,11 +167,43 @@ impl<'a> RegionProcessor<'a> { } } +struct TileRenderer<'a> { + paths: &'a Paths, +} + +impl<'a> TileRenderer<'a> { + fn new(paths: &'a Paths) -> Self { + TileRenderer { paths } + } + + fn render_tile(&self, coords: RegionCoords) -> Result<()> { + println!("Rendering tile r.{}.{}.png", coords.0, coords.1); + + Ok(()) + } + + fn run(self, regions: &[RegionCoords]) -> Result<()> { + fs::create_dir_all(&self.paths.map_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.paths.map_dir.display(), + ) + })?; + + for &coords in regions { + self.render_tile(coords)?; + } + + Ok(()) + } +} + fn main() -> Result<()> { let args = Args::parse(); let paths = Paths::new(args); - RegionProcessor::new(&paths).run()?; + let regions = RegionProcessor::new(&paths).run()?; + TileRenderer::new(&paths).run(®ions)?; Ok(()) } From cbbc6d8f3529675c72232f82d2946de5a7a5deb2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 21:54:40 +0100 Subject: [PATCH 110/460] resource: make BlockTypeMap return BlockType without reference --- src/resource/mod.rs | 19 ++++++++++++++----- src/world/layer.rs | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 7f3a499..3d1dc96 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -53,11 +53,20 @@ impl BlockType { } } -pub type BlockTypeMap = HashMap; +pub struct BlockTypeMap(HashMap); + +impl BlockTypeMap { + #[inline] + pub fn get(&self, id: &str) -> Option { + self.0.get(id).copied() + } +} pub fn block_types() -> BlockTypeMap { - block_types::BLOCK_TYPES - .iter() - .map(|(k, v)| (String::from(*k), *v)) - .collect() + BlockTypeMap( + block_types::BLOCK_TYPES + .iter() + .map(|(k, v)| (String::from(*k), *v)) + .collect(), + ) } diff --git a/src/world/layer.rs b/src/world/layer.rs index f8a7302..2232af8 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -110,7 +110,7 @@ pub fn top_layer(chunk: &Chunk, block_types: &BlockTypeMap) -> Result Date: Wed, 1 Mar 2023 22:01:30 +0100 Subject: [PATCH 111/460] resource: update block_types with Minecraft 1.19.2 data An older Minecraft version had been used to generate the data for the Rust rewrite by accident. --- src/resource/block_types.rs | 255 +++++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 5 deletions(-) diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index 5b975c2..ea32d9a 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -707,7 +707,7 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "minecraft:brewing_stand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(123, 101, 81), + color: BlockColor(122, 100, 80), }, ), ( @@ -1169,7 +1169,7 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "minecraft:cocoa", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(156, 94, 43), + color: BlockColor(154, 91, 40), }, ), ( @@ -2264,6 +2264,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(99, 111, 60), }, ), + ( + "minecraft:frogspawn", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(105, 90, 82), + }, + ), ( "minecraft:frosted_ice", BlockType { @@ -3426,6 +3433,118 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(142, 63, 31), }, ), + ( + "minecraft:mangrove_button", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:mangrove_door", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(112, 48, 46), + }, + ), + ( + "minecraft:mangrove_fence", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_leaves", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), + color: BlockColor(129, 128, 128), + }, + ), + ( + "minecraft:mangrove_log", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(102, 48, 42), + }, + ), + ( + "minecraft:mangrove_planks", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_propagule", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(96, 174, 83), + }, + ), + ( + "minecraft:mangrove_roots", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(74, 59, 38), + }, + ), + ( + "minecraft:mangrove_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_slab", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_stairs", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(117, 54, 48), + }, + ), + ( + "minecraft:mangrove_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(110, 46, 42), + }, + ), + ( + "minecraft:mangrove_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: BlockColor(0, 0, 0), + }, + ), + ( + "minecraft:mangrove_wood", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(83, 66, 41), + }, + ), ( "minecraft:medium_amethyst_bud", BlockType { @@ -3524,6 +3643,48 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(0, 0, 0), }, ), + ( + "minecraft:mud", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(60, 57, 60), + }, + ), + ( + "minecraft:mud_brick_slab", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(137, 103, 79), + }, + ), + ( + "minecraft:mud_brick_stairs", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(137, 103, 79), + }, + ), + ( + "minecraft:mud_brick_wall", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(137, 103, 79), + }, + ), + ( + "minecraft:mud_bricks", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(137, 103, 79), + }, + ), + ( + "minecraft:muddy_mangrove_roots", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(70, 58, 45), + }, + ), ( "minecraft:mushroom_stem", BlockType { @@ -3755,6 +3916,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(15, 10, 24), }, ), + ( + "minecraft:ochre_froglight", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(250, 245, 206), + }, + ), ( "minecraft:orange_banner", BlockType { @@ -3902,6 +4070,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(141, 180, 250), }, ), + ( + "minecraft:packed_mud", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(142, 106, 79), + }, + ), + ( + "minecraft:pearlescent_froglight", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(245, 240, 239), + }, + ), ( "minecraft:peony", BlockType { @@ -4025,14 +4207,14 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "minecraft:piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 104, 96), + color: BlockColor(109, 104, 96), }, ), ( "minecraft:piston_head", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 127, 87), + color: BlockColor(153, 127, 85), }, ), ( @@ -4378,6 +4560,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(123, 174, 95), }, ), + ( + "minecraft:potted_mangrove_propagule", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(96, 174, 83), + }, + ), ( "minecraft:potted_oak_sapling", BlockType { @@ -4959,6 +5148,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(175, 24, 5), }, ), + ( + "minecraft:reinforced_deepslate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(80, 82, 78), + }, + ), ( "minecraft:repeater", BlockType { @@ -5036,6 +5232,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(174, 134, 80), }, ), + ( + "minecraft:sculk", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(12, 29, 36), + }, + ), + ( + "minecraft:sculk_catalyst", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(15, 31, 38), + }, + ), ( "minecraft:sculk_sensor", BlockType { @@ -5043,6 +5253,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(7, 70, 84), }, ), + ( + "minecraft:sculk_shrieker", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(198, 205, 169), + }, + ), + ( + "minecraft:sculk_vein", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(7, 48, 57), + }, + ), ( "minecraft:sea_lantern", BlockType { @@ -5411,7 +5635,7 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "minecraft:sticky_piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 104, 96), + color: BlockColor(109, 104, 96), }, ), ( @@ -5554,6 +5778,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(171, 132, 84), }, ), + ( + "minecraft:stripped_mangrove_log", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(109, 43, 43), + }, + ), + ( + "minecraft:stripped_mangrove_wood", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(119, 54, 47), + }, + ), ( "minecraft:stripped_oak_log", BlockType { @@ -5757,6 +5995,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: BlockColor(20, 135, 122), }, ), + ( + "minecraft:verdant_froglight", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: BlockColor(229, 244, 228), + }, + ), ( "minecraft:vine", BlockType { From 95e4e459748c19ae27f3987f26a661c582f6da2d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 21:58:43 +0100 Subject: [PATCH 112/460] resource: remove "minecraft:" prefix from hash keys Shorter keys mean less data to hash. --- resource/extract.py | 2 +- src/resource/block_types.rs | 1876 +++++++++++++++++------------------ src/resource/mod.rs | 3 +- 3 files changed, 941 insertions(+), 940 deletions(-) diff --git a/resource/extract.py b/resource/extract.py index 4e992c2..281f3a7 100755 --- a/resource/extract.py +++ b/resource/extract.py @@ -35,7 +35,7 @@ with open(sys.argv[1]) as f: output = {} for name, info in blocks.items(): - id = 'minecraft:' + name + id = name output[id] = { 'color': {'r': 0, 'g': 0, 'b': 0}, diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index ea32d9a..6afed2a 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -4,6566 +4,6566 @@ use super::*; pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ ( - "minecraft:acacia_button", + "acacia_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:acacia_door", + "acacia_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(167, 95, 60), }, ), ( - "minecraft:acacia_fence", + "acacia_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_fence_gate", + "acacia_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_leaves", + "acacia_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(149, 148, 148), }, ), ( - "minecraft:acacia_log", + "acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 88, 55), }, ), ( - "minecraft:acacia_planks", + "acacia_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_pressure_plate", + "acacia_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_sapling", + "acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 23), }, ), ( - "minecraft:acacia_sign", + "acacia_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_slab", + "acacia_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_stairs", + "acacia_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 90, 50), }, ), ( - "minecraft:acacia_trapdoor", + "acacia_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(156, 87, 51), }, ), ( - "minecraft:acacia_wall_sign", + "acacia_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:acacia_wood", + "acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 96, 86), }, ), ( - "minecraft:activator_rail", + "activator_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 87, 74), }, ), ( - "minecraft:air", + "air", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:allium", + "allium", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:amethyst_block", + "amethyst_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(133, 97, 191), }, ), ( - "minecraft:amethyst_cluster", + "amethyst_cluster", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 126, 207), }, ), ( - "minecraft:ancient_debris", + "ancient_debris", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 66, 58), }, ), ( - "minecraft:andesite", + "andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( - "minecraft:andesite_slab", + "andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( - "minecraft:andesite_stairs", + "andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( - "minecraft:andesite_wall", + "andesite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 136, 136), }, ), ( - "minecraft:anvil", + "anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( - "minecraft:attached_melon_stem", + "attached_melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(141, 142, 141), }, ), ( - "minecraft:attached_pumpkin_stem", + "attached_pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(139, 139, 139), }, ), ( - "minecraft:azalea", + "azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 124, 47), }, ), ( - "minecraft:azalea_leaves", + "azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 114, 44), }, ), ( - "minecraft:azure_bluet", + "azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:bamboo", + "bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 144, 19), }, ), ( - "minecraft:bamboo_sapling", + "bamboo_sapling", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:barrel", + "barrel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 100, 58), }, ), ( - "minecraft:barrier", + "barrier", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:basalt", + "basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 81, 86), }, ), ( - "minecraft:beacon", + "beacon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 220, 215), }, ), ( - "minecraft:bedrock", + "bedrock", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 85, 85), }, ), ( - "minecraft:bee_nest", + "bee_nest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(202, 160, 74), }, ), ( - "minecraft:beehive", + "beehive", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(180, 146, 90), }, ), ( - "minecraft:beetroots", + "beetroots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 91, 30), }, ), ( - "minecraft:bell", + "bell", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(253, 235, 110), }, ), ( - "minecraft:big_dripleaf", + "big_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 141, 51), }, ), ( - "minecraft:big_dripleaf_stem", + "big_dripleaf_stem", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:birch_button", + "birch_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:birch_door", + "birch_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 209, 176), }, ), ( - "minecraft:birch_fence", + "birch_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_fence_gate", + "birch_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_leaves", + "birch_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Birch}), color: BlockColor(130, 129, 130), }, ), ( - "minecraft:birch_log", + "birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(193, 179, 135), }, ), ( - "minecraft:birch_planks", + "birch_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_pressure_plate", + "birch_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_sapling", + "birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 160, 79), }, ), ( - "minecraft:birch_sign", + "birch_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_slab", + "birch_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_stairs", + "birch_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 175, 121), }, ), ( - "minecraft:birch_trapdoor", + "birch_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 194, 157), }, ), ( - "minecraft:birch_wall_sign", + "birch_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:birch_wood", + "birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 215, 210), }, ), ( - "minecraft:black_banner", + "black_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:black_bed", + "black_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:black_candle", + "black_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:black_candle_cake", + "black_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:black_carpet", + "black_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 21, 25), }, ), ( - "minecraft:black_concrete", + "black_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(8, 10, 15), }, ), ( - "minecraft:black_concrete_powder", + "black_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 26, 31), }, ), ( - "minecraft:black_glazed_terracotta", + "black_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(67, 30, 32), }, ), ( - "minecraft:black_shulker_box", + "black_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 25, 29), }, ), ( - "minecraft:black_stained_glass", + "black_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(25, 25, 25), }, ), ( - "minecraft:black_stained_glass_pane", + "black_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(24, 24, 24), }, ), ( - "minecraft:black_terracotta", + "black_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(37, 22, 16), }, ), ( - "minecraft:black_wall_banner", + "black_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:black_wool", + "black_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 21, 25), }, ), ( - "minecraft:blackstone", + "blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( - "minecraft:blackstone_slab", + "blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( - "minecraft:blackstone_stairs", + "blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( - "minecraft:blackstone_wall", + "blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 36, 41), }, ), ( - "minecraft:blast_furnace", + "blast_furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 81), }, ), ( - "minecraft:blue_banner", + "blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:blue_bed", + "blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:blue_candle", + "blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:blue_candle_cake", + "blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:blue_carpet", + "blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 57, 157), }, ), ( - "minecraft:blue_concrete", + "blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 46, 143), }, ), ( - "minecraft:blue_concrete_powder", + "blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 73, 166), }, ), ( - "minecraft:blue_glazed_terracotta", + "blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 64, 139), }, ), ( - "minecraft:blue_ice", + "blue_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(116, 167, 253), }, ), ( - "minecraft:blue_orchid", + "blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:blue_shulker_box", + "blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 45, 140), }, ), ( - "minecraft:blue_stained_glass", + "blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 76, 178), }, ), ( - "minecraft:blue_stained_glass_pane", + "blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 73, 171), }, ), ( - "minecraft:blue_terracotta", + "blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 59, 91), }, ), ( - "minecraft:blue_wall_banner", + "blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:blue_wool", + "blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 57, 157), }, ), ( - "minecraft:bone_block", + "bone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(209, 206, 179), }, ), ( - "minecraft:bookshelf", + "bookshelf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:brain_coral", + "brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brain_coral_block", + "brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 91, 159), }, ), ( - "minecraft:brain_coral_fan", + "brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brain_coral_wall_fan", + "brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brewing_stand", + "brewing_stand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 100, 80), }, ), ( - "minecraft:brick_slab", + "brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( - "minecraft:brick_stairs", + "brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( - "minecraft:brick_wall", + "brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( - "minecraft:bricks", + "bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(150, 97, 83), }, ), ( - "minecraft:brown_banner", + "brown_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brown_bed", + "brown_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brown_candle", + "brown_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brown_candle_cake", + "brown_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:brown_carpet", + "brown_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 71, 40), }, ), ( - "minecraft:brown_concrete", + "brown_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(96, 59, 31), }, ), ( - "minecraft:brown_concrete_powder", + "brown_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 84, 53), }, ), ( - "minecraft:brown_glazed_terracotta", + "brown_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 106, 85), }, ), ( - "minecraft:brown_mushroom", + "brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brown_mushroom_block", + "brown_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 111, 81), }, ), ( - "minecraft:brown_shulker_box", + "brown_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 66, 35), }, ), ( - "minecraft:brown_stained_glass", + "brown_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 76, 51), }, ), ( - "minecraft:brown_stained_glass_pane", + "brown_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 73, 48), }, ), ( - "minecraft:brown_terracotta", + "brown_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 51, 35), }, ), ( - "minecraft:brown_wall_banner", + "brown_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:brown_wool", + "brown_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 71, 40), }, ), ( - "minecraft:bubble_column", + "bubble_column", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: BlockColor(177, 177, 177), }, ), ( - "minecraft:bubble_coral", + "bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:bubble_coral_block", + "bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 26, 162), }, ), ( - "minecraft:bubble_coral_fan", + "bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:bubble_coral_wall_fan", + "bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:budding_amethyst", + "budding_amethyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 96, 186), }, ), ( - "minecraft:cactus", + "cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 127, 43), }, ), ( - "minecraft:cake", + "cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:calcite", + "calcite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 224, 220), }, ), ( - "minecraft:campfire", + "campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 88, 54), }, ), ( - "minecraft:candle", + "candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:candle_cake", + "candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:carrots", + "carrots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 124, 37), }, ), ( - "minecraft:cartography_table", + "cartography_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 87, 67), }, ), ( - "minecraft:carved_pumpkin", + "carved_pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(198, 118, 24), }, ), ( - "minecraft:cauldron", + "cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( - "minecraft:cave_air", + "cave_air", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cave_vines", + "cave_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 109, 40), }, ), ( - "minecraft:cave_vines_plant", + "cave_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 101, 38), }, ), ( - "minecraft:chain", + "chain", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:chain_command_block", + "chain_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 161, 147), }, ), ( - "minecraft:chest", + "chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:chipped_anvil", + "chipped_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( - "minecraft:chiseled_deepslate", + "chiseled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 54), }, ), ( - "minecraft:chiseled_nether_bricks", + "chiseled_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 23, 28), }, ), ( - "minecraft:chiseled_polished_blackstone", + "chiseled_polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:chiseled_quartz_block", + "chiseled_quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(231, 226, 218), }, ), ( - "minecraft:chiseled_red_sandstone", + "chiseled_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:chiseled_sandstone", + "chiseled_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:chiseled_stone_bricks", + "chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 118, 119), }, ), ( - "minecraft:chorus_flower", + "chorus_flower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(151, 120, 151), }, ), ( - "minecraft:chorus_plant", + "chorus_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 57, 93), }, ), ( - "minecraft:clay", + "clay", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 166, 179), }, ), ( - "minecraft:coal_block", + "coal_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(16, 15, 15), }, ), ( - "minecraft:coal_ore", + "coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(105, 105, 105), }, ), ( - "minecraft:coarse_dirt", + "coarse_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 85, 59), }, ), ( - "minecraft:cobbled_deepslate", + "cobbled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( - "minecraft:cobbled_deepslate_slab", + "cobbled_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( - "minecraft:cobbled_deepslate_stairs", + "cobbled_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( - "minecraft:cobbled_deepslate_wall", + "cobbled_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 77, 80), }, ), ( - "minecraft:cobblestone", + "cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( - "minecraft:cobblestone_slab", + "cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( - "minecraft:cobblestone_stairs", + "cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( - "minecraft:cobblestone_wall", + "cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( - "minecraft:cobweb", + "cobweb", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 233, 234), }, ), ( - "minecraft:cocoa", + "cocoa", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 91, 40), }, ), ( - "minecraft:command_block", + "command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 136, 108), }, ), ( - "minecraft:comparator", + "comparator", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 161, 159), }, ), ( - "minecraft:composter", + "composter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 61, 23), }, ), ( - "minecraft:conduit", + "conduit", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(159, 139, 113), }, ), ( - "minecraft:copper_block", + "copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 107, 79), }, ), ( - "minecraft:copper_ore", + "copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 125, 120), }, ), ( - "minecraft:cornflower", + "cornflower", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cracked_deepslate_bricks", + "cracked_deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(64, 64, 65), }, ), ( - "minecraft:cracked_deepslate_tiles", + "cracked_deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 52, 52), }, ), ( - "minecraft:cracked_nether_bricks", + "cracked_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(40, 20, 23), }, ), ( - "minecraft:cracked_polished_blackstone_bricks", + "cracked_polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 37, 43), }, ), ( - "minecraft:cracked_stone_bricks", + "cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 118), }, ), ( - "minecraft:crafting_table", + "crafting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 73, 42), }, ), ( - "minecraft:creeper_head", + "creeper_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:creeper_wall_head", + "creeper_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:crimson_button", + "crimson_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:crimson_door", + "crimson_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 54, 79), }, ), ( - "minecraft:crimson_fence", + "crimson_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_fence_gate", + "crimson_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_fungus", + "crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:crimson_hyphae", + "crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(92, 25, 29), }, ), ( - "minecraft:crimson_nylium", + "crimson_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 31, 31), }, ), ( - "minecraft:crimson_planks", + "crimson_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_pressure_plate", + "crimson_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_roots", + "crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(126, 8, 41), }, ), ( - "minecraft:crimson_sign", + "crimson_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_slab", + "crimson_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_stairs", + "crimson_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 48, 70), }, ), ( - "minecraft:crimson_stem", + "crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 49, 70), }, ), ( - "minecraft:crimson_trapdoor", + "crimson_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 50, 72), }, ), ( - "minecraft:crimson_wall_sign", + "crimson_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:crying_obsidian", + "crying_obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(32, 10, 60), }, ), ( - "minecraft:cut_copper", + "cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:cut_copper_slab", + "cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:cut_copper_stairs", + "cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:cut_red_sandstone", + "cut_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:cut_red_sandstone_slab", + "cut_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:cut_sandstone", + "cut_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:cut_sandstone_slab", + "cut_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:cyan_banner", + "cyan_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cyan_bed", + "cyan_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cyan_candle", + "cyan_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cyan_candle_cake", + "cyan_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:cyan_carpet", + "cyan_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 137, 145), }, ), ( - "minecraft:cyan_concrete", + "cyan_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 119, 136), }, ), ( - "minecraft:cyan_concrete_powder", + "cyan_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(36, 147, 157), }, ), ( - "minecraft:cyan_glazed_terracotta", + "cyan_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 118, 125), }, ), ( - "minecraft:cyan_shulker_box", + "cyan_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 121, 135), }, ), ( - "minecraft:cyan_stained_glass", + "cyan_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 127, 153), }, ), ( - "minecraft:cyan_stained_glass_pane", + "cyan_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 122, 147), }, ), ( - "minecraft:cyan_terracotta", + "cyan_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(86, 91, 91), }, ), ( - "minecraft:cyan_wall_banner", + "cyan_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:cyan_wool", + "cyan_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(21, 137, 145), }, ), ( - "minecraft:damaged_anvil", + "damaged_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 72), }, ), ( - "minecraft:dandelion", + "dandelion", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dark_oak_button", + "dark_oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dark_oak_door", + "dark_oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 51, 25), }, ), ( - "minecraft:dark_oak_fence", + "dark_oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_fence_gate", + "dark_oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_leaves", + "dark_oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(150, 150, 150), }, ), ( - "minecraft:dark_oak_log", + "dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(67, 45, 22), }, ), ( - "minecraft:dark_oak_planks", + "dark_oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_pressure_plate", + "dark_oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_sapling", + "dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(61, 90, 30), }, ), ( - "minecraft:dark_oak_sign", + "dark_oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_slab", + "dark_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_stairs", + "dark_oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 43, 20), }, ), ( - "minecraft:dark_oak_trapdoor", + "dark_oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 49, 23), }, ), ( - "minecraft:dark_oak_wall_sign", + "dark_oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dark_oak_wood", + "dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(60, 46, 26), }, ), ( - "minecraft:dark_prismarine", + "dark_prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( - "minecraft:dark_prismarine_slab", + "dark_prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( - "minecraft:dark_prismarine_stairs", + "dark_prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 91, 75), }, ), ( - "minecraft:daylight_detector", + "daylight_detector", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 116, 94), }, ), ( - "minecraft:dead_brain_coral", + "dead_brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_brain_coral_block", + "dead_brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 117, 114), }, ), ( - "minecraft:dead_brain_coral_fan", + "dead_brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_brain_coral_wall_fan", + "dead_brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_bubble_coral", + "dead_bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_bubble_coral_block", + "dead_bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 123, 119), }, ), ( - "minecraft:dead_bubble_coral_fan", + "dead_bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_bubble_coral_wall_fan", + "dead_bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_bush", + "dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 78, 40), }, ), ( - "minecraft:dead_fire_coral", + "dead_fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_fire_coral_block", + "dead_fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 123, 119), }, ), ( - "minecraft:dead_fire_coral_fan", + "dead_fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_fire_coral_wall_fan", + "dead_fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_horn_coral", + "dead_horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_horn_coral_block", + "dead_horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(133, 126, 122), }, ), ( - "minecraft:dead_horn_coral_fan", + "dead_horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_horn_coral_wall_fan", + "dead_horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_tube_coral", + "dead_tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_tube_coral_block", + "dead_tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(130, 123, 119), }, ), ( - "minecraft:dead_tube_coral_fan", + "dead_tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dead_tube_coral_wall_fan", + "dead_tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:deepslate", + "deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 82), }, ), ( - "minecraft:deepslate_brick_slab", + "deepslate_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( - "minecraft:deepslate_brick_stairs", + "deepslate_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( - "minecraft:deepslate_brick_wall", + "deepslate_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( - "minecraft:deepslate_bricks", + "deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 70, 71), }, ), ( - "minecraft:deepslate_coal_ore", + "deepslate_coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 74, 76), }, ), ( - "minecraft:deepslate_copper_ore", + "deepslate_copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(92, 93, 89), }, ), ( - "minecraft:deepslate_diamond_ore", + "deepslate_diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(83, 106, 106), }, ), ( - "minecraft:deepslate_emerald_ore", + "deepslate_emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(78, 104, 87), }, ), ( - "minecraft:deepslate_gold_ore", + "deepslate_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 102, 78), }, ), ( - "minecraft:deepslate_iron_ore", + "deepslate_iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 99, 94), }, ), ( - "minecraft:deepslate_lapis_ore", + "deepslate_lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 90, 115), }, ), ( - "minecraft:deepslate_redstone_ore", + "deepslate_redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(104, 73, 74), }, ), ( - "minecraft:deepslate_tile_slab", + "deepslate_tile_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( - "minecraft:deepslate_tile_stairs", + "deepslate_tile_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( - "minecraft:deepslate_tile_wall", + "deepslate_tile_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( - "minecraft:deepslate_tiles", + "deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 54, 55), }, ), ( - "minecraft:detector_rail", + "detector_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 104, 90), }, ), ( - "minecraft:diamond_block", + "diamond_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(98, 237, 228), }, ), ( - "minecraft:diamond_ore", + "diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 141, 140), }, ), ( - "minecraft:diorite", + "diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( - "minecraft:diorite_slab", + "diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( - "minecraft:diorite_stairs", + "diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( - "minecraft:diorite_wall", + "diorite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 188, 188), }, ), ( - "minecraft:dirt", + "dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 96, 67), }, ), ( - "minecraft:dirt_path", + "dirt_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 121, 65), }, ), ( - "minecraft:dispenser", + "dispenser", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( - "minecraft:dragon_egg", + "dragon_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(12, 9, 15), }, ), ( - "minecraft:dragon_head", + "dragon_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dragon_wall_head", + "dragon_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:dried_kelp_block", + "dried_kelp_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(50, 58, 38), }, ), ( - "minecraft:dripstone_block", + "dripstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(134, 107, 92), }, ), ( - "minecraft:dropper", + "dropper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( - "minecraft:emerald_block", + "emerald_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(42, 203, 87), }, ), ( - "minecraft:emerald_ore", + "emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 136, 115), }, ), ( - "minecraft:enchanting_table", + "enchanting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(128, 75, 85), }, ), ( - "minecraft:end_gateway", + "end_gateway", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( - "minecraft:end_portal", + "end_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( - "minecraft:end_portal_frame", + "end_portal_frame", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(91, 120, 97), }, ), ( - "minecraft:end_rod", + "end_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:end_stone", + "end_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(219, 222, 158), }, ), ( - "minecraft:end_stone_brick_slab", + "end_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( - "minecraft:end_stone_brick_stairs", + "end_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( - "minecraft:end_stone_brick_wall", + "end_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( - "minecraft:end_stone_bricks", + "end_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(218, 224, 162), }, ), ( - "minecraft:ender_chest", + "ender_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( - "minecraft:exposed_copper", + "exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 125, 103), }, ), ( - "minecraft:exposed_cut_copper", + "exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:exposed_cut_copper_slab", + "exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:exposed_cut_copper_stairs", + "exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:farmland", + "farmland", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 44, 15), }, ), ( - "minecraft:fern", + "fern", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:fire", + "fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(211, 140, 53), }, ), ( - "minecraft:fire_coral", + "fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:fire_coral_block", + "fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 35, 46), }, ), ( - "minecraft:fire_coral_fan", + "fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:fire_coral_wall_fan", + "fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:fletching_table", + "fletching_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(197, 180, 133), }, ), ( - "minecraft:flower_pot", + "flower_pot", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 68, 53), }, ), ( - "minecraft:flowering_azalea", + "flowering_azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 121, 64), }, ), ( - "minecraft:flowering_azalea_leaves", + "flowering_azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 111, 60), }, ), ( - "minecraft:frogspawn", + "frogspawn", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(105, 90, 82), }, ), ( - "minecraft:frosted_ice", + "frosted_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 181, 252), }, ), ( - "minecraft:furnace", + "furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 109, 109), }, ), ( - "minecraft:gilded_blackstone", + "gilded_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(55, 42, 38), }, ), ( - "minecraft:glass", + "glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 213, 219), }, ), ( - "minecraft:glass_pane", + "glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(170, 210, 217), }, ), ( - "minecraft:glow_item_frame", + "glow_item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:glow_lichen", + "glow_lichen", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:glowstone", + "glowstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 131, 84), }, ), ( - "minecraft:gold_block", + "gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 208, 61), }, ), ( - "minecraft:gold_ore", + "gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(145, 133, 106), }, ), ( - "minecraft:granite", + "granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( - "minecraft:granite_slab", + "granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( - "minecraft:granite_stairs", + "granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( - "minecraft:granite_wall", + "granite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 103, 85), }, ), ( - "minecraft:grass", + "grass", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:grass_block", + "grass_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(147, 147, 147), }, ), ( - "minecraft:grass_path", + "grass_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 121, 65), }, ), ( - "minecraft:gravel", + "gravel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 127, 126), }, ), ( - "minecraft:gray_banner", + "gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:gray_bed", + "gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:gray_candle", + "gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:gray_candle_cake", + "gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:gray_carpet", + "gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(62, 68, 71), }, ), ( - "minecraft:gray_concrete", + "gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(54, 57, 61), }, ), ( - "minecraft:gray_concrete_powder", + "gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 81, 84), }, ), ( - "minecraft:gray_glazed_terracotta", + "gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(83, 90, 93), }, ), ( - "minecraft:gray_shulker_box", + "gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(55, 58, 62), }, ), ( - "minecraft:gray_stained_glass", + "gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 76, 76), }, ), ( - "minecraft:gray_stained_glass_pane", + "gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 73, 73), }, ), ( - "minecraft:gray_terracotta", + "gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 42, 35), }, ), ( - "minecraft:gray_wall_banner", + "gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:gray_wool", + "gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(62, 68, 71), }, ), ( - "minecraft:green_banner", + "green_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:green_bed", + "green_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:green_candle", + "green_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:green_candle_cake", + "green_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:green_carpet", + "green_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 109, 27), }, ), ( - "minecraft:green_concrete", + "green_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 91, 36), }, ), ( - "minecraft:green_concrete_powder", + "green_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 119, 44), }, ), ( - "minecraft:green_glazed_terracotta", + "green_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 142, 67), }, ), ( - "minecraft:green_shulker_box", + "green_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 100, 31), }, ), ( - "minecraft:green_stained_glass", + "green_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 127, 51), }, ), ( - "minecraft:green_stained_glass_pane", + "green_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 122, 48), }, ), ( - "minecraft:green_terracotta", + "green_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(76, 83, 42), }, ), ( - "minecraft:green_wall_banner", + "green_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:green_wool", + "green_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 109, 27), }, ), ( - "minecraft:grindstone", + "grindstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 142), }, ), ( - "minecraft:hanging_roots", + "hanging_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 115, 91), }, ), ( - "minecraft:hay_block", + "hay_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 139, 12), }, ), ( - "minecraft:heavy_weighted_pressure_plate", + "heavy_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 220, 220), }, ), ( - "minecraft:honey_block", + "honey_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(251, 185, 52), }, ), ( - "minecraft:honeycomb_block", + "honeycomb_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(229, 148, 29), }, ), ( - "minecraft:hopper", + "hopper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 74, 75), }, ), ( - "minecraft:horn_coral", + "horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:horn_coral_block", + "horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 199, 66), }, ), ( - "minecraft:horn_coral_fan", + "horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:horn_coral_wall_fan", + "horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:ice", + "ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(145, 183, 253), }, ), ( - "minecraft:infested_chiseled_stone_bricks", + "infested_chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 118, 119), }, ), ( - "minecraft:infested_cobblestone", + "infested_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 127, 127), }, ), ( - "minecraft:infested_cracked_stone_bricks", + "infested_cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 118), }, ), ( - "minecraft:infested_deepslate", + "infested_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 80, 82), }, ), ( - "minecraft:infested_mossy_stone_bricks", + "infested_mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( - "minecraft:infested_stone", + "infested_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:infested_stone_bricks", + "infested_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( - "minecraft:iron_bars", + "iron_bars", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 139, 135), }, ), ( - "minecraft:iron_block", + "iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(220, 220, 220), }, ), ( - "minecraft:iron_door", + "iron_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(194, 193, 193), }, ), ( - "minecraft:iron_ore", + "iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(136, 129, 122), }, ), ( - "minecraft:iron_trapdoor", + "iron_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(202, 202, 202), }, ), ( - "minecraft:item_frame", + "item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:jack_o_lantern", + "jack_o_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(214, 152, 52), }, ), ( - "minecraft:jigsaw", + "jigsaw", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 69, 81), }, ), ( - "minecraft:jukebox", + "jukebox", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 64, 47), }, ), ( - "minecraft:jungle_button", + "jungle_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:jungle_door", + "jungle_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(163, 119, 84), }, ), ( - "minecraft:jungle_fence", + "jungle_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_fence_gate", + "jungle_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_leaves", + "jungle_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(156, 154, 143), }, ), ( - "minecraft:jungle_log", + "jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 109, 70), }, ), ( - "minecraft:jungle_planks", + "jungle_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_pressure_plate", + "jungle_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_sapling", + "jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 81, 16), }, ), ( - "minecraft:jungle_sign", + "jungle_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_slab", + "jungle_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_stairs", + "jungle_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 115, 80), }, ), ( - "minecraft:jungle_trapdoor", + "jungle_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(152, 110, 77), }, ), ( - "minecraft:jungle_wall_sign", + "jungle_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:jungle_wood", + "jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 67, 25), }, ), ( - "minecraft:kelp", + "kelp", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:kelp_plant", + "kelp_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(86, 130, 42), }, ), ( - "minecraft:ladder", + "ladder", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lantern", + "lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 91, 83), }, ), ( - "minecraft:lapis_block", + "lapis_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(30, 67, 140), }, ), ( - "minecraft:lapis_ore", + "lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 117, 141), }, ), ( - "minecraft:large_amethyst_bud", + "large_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:large_fern", + "large_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:lava", + "lava", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(212, 90, 18), }, ), ( - "minecraft:lava_cauldron", + "lava_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( - "minecraft:lectern", + "lectern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(173, 137, 83), }, ), ( - "minecraft:lever", + "lever", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light", + "light", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_blue_banner", + "light_blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_blue_bed", + "light_blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_blue_candle", + "light_blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_blue_candle_cake", + "light_blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:light_blue_carpet", + "light_blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 175, 217), }, ), ( - "minecraft:light_blue_concrete", + "light_blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(35, 137, 198), }, ), ( - "minecraft:light_blue_concrete_powder", + "light_blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 180, 213), }, ), ( - "minecraft:light_blue_glazed_terracotta", + "light_blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 164, 208), }, ), ( - "minecraft:light_blue_shulker_box", + "light_blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(49, 163, 212), }, ), ( - "minecraft:light_blue_stained_glass", + "light_blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 153, 216), }, ), ( - "minecraft:light_blue_stained_glass_pane", + "light_blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 147, 208), }, ), ( - "minecraft:light_blue_terracotta", + "light_blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(113, 108, 137), }, ), ( - "minecraft:light_blue_wall_banner", + "light_blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_blue_wool", + "light_blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 175, 217), }, ), ( - "minecraft:light_gray_banner", + "light_gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_gray_bed", + "light_gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_gray_candle", + "light_gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_gray_candle_cake", + "light_gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:light_gray_carpet", + "light_gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 134), }, ), ( - "minecraft:light_gray_concrete", + "light_gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 115), }, ), ( - "minecraft:light_gray_concrete_powder", + "light_gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 154, 148), }, ), ( - "minecraft:light_gray_glazed_terracotta", + "light_gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(144, 166, 167), }, ), ( - "minecraft:light_gray_shulker_box", + "light_gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 124, 115), }, ), ( - "minecraft:light_gray_stained_glass", + "light_gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 153, 153), }, ), ( - "minecraft:light_gray_stained_glass_pane", + "light_gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 147, 147), }, ), ( - "minecraft:light_gray_terracotta", + "light_gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(135, 106, 97), }, ), ( - "minecraft:light_gray_wall_banner", + "light_gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:light_gray_wool", + "light_gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 142, 134), }, ), ( - "minecraft:light_weighted_pressure_plate", + "light_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 208, 61), }, ), ( - "minecraft:lightning_rod", + "lightning_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lilac", + "lilac", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 125, 147), }, ), ( - "minecraft:lily_of_the_valley", + "lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lily_pad", + "lily_pad", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(133, 133, 133), }, ), ( - "minecraft:lime_banner", + "lime_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lime_bed", + "lime_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lime_candle", + "lime_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lime_candle_cake", + "lime_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:lime_carpet", + "lime_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 185, 25), }, ), ( - "minecraft:lime_concrete", + "lime_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(94, 168, 24), }, ), ( - "minecraft:lime_concrete_powder", + "lime_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 189, 41), }, ), ( - "minecraft:lime_glazed_terracotta", + "lime_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 197, 55), }, ), ( - "minecraft:lime_shulker_box", + "lime_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 172, 23), }, ), ( - "minecraft:lime_stained_glass", + "lime_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 204, 25), }, ), ( - "minecraft:lime_stained_glass_pane", + "lime_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 196, 24), }, ), ( - "minecraft:lime_terracotta", + "lime_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 117, 52), }, ), ( - "minecraft:lime_wall_banner", + "lime_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:lime_wool", + "lime_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 185, 25), }, ), ( - "minecraft:lodestone", + "lodestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 149, 152), }, ), ( - "minecraft:loom", + "loom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 119, 91), }, ), ( - "minecraft:magenta_banner", + "magenta_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:magenta_bed", + "magenta_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:magenta_candle", + "magenta_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:magenta_candle_cake", + "magenta_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:magenta_carpet", + "magenta_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(189, 68, 179), }, ), ( - "minecraft:magenta_concrete", + "magenta_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 48, 159), }, ), ( - "minecraft:magenta_concrete_powder", + "magenta_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 83, 184), }, ), ( - "minecraft:magenta_glazed_terracotta", + "magenta_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(208, 100, 191), }, ), ( - "minecraft:magenta_shulker_box", + "magenta_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(173, 54, 163), }, ), ( - "minecraft:magenta_stained_glass", + "magenta_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(178, 76, 216), }, ), ( - "minecraft:magenta_stained_glass_pane", + "magenta_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 73, 208), }, ), ( - "minecraft:magenta_terracotta", + "magenta_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(149, 88, 108), }, ), ( - "minecraft:magenta_wall_banner", + "magenta_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:magenta_wool", + "magenta_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(189, 68, 179), }, ), ( - "minecraft:magma_block", + "magma_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 63, 31), }, ), ( - "minecraft:mangrove_button", + "mangrove_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:mangrove_door", + "mangrove_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 48, 46), }, ), ( - "minecraft:mangrove_fence", + "mangrove_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_fence_gate", + "mangrove_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_leaves", + "mangrove_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(129, 128, 128), }, ), ( - "minecraft:mangrove_log", + "mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(102, 48, 42), }, ), ( - "minecraft:mangrove_planks", + "mangrove_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_pressure_plate", + "mangrove_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_propagule", + "mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(96, 174, 83), }, ), ( - "minecraft:mangrove_roots", + "mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 59, 38), }, ), ( - "minecraft:mangrove_sign", + "mangrove_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_slab", + "mangrove_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_stairs", + "mangrove_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 54, 48), }, ), ( - "minecraft:mangrove_trapdoor", + "mangrove_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 46, 42), }, ), ( - "minecraft:mangrove_wall_sign", + "mangrove_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:mangrove_wood", + "mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(83, 66, 41), }, ), ( - "minecraft:medium_amethyst_bud", + "medium_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:melon", + "melon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 144, 30), }, ), ( - "minecraft:melon_stem", + "melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(153, 153, 153), }, ), ( - "minecraft:moss_block", + "moss_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 109, 45), }, ), ( - "minecraft:moss_carpet", + "moss_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 109, 45), }, ), ( - "minecraft:mossy_cobblestone", + "mossy_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( - "minecraft:mossy_cobblestone_slab", + "mossy_cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( - "minecraft:mossy_cobblestone_stairs", + "mossy_cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( - "minecraft:mossy_cobblestone_wall", + "mossy_cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(110, 118, 94), }, ), ( - "minecraft:mossy_stone_brick_slab", + "mossy_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( - "minecraft:mossy_stone_brick_stairs", + "mossy_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( - "minecraft:mossy_stone_brick_wall", + "mossy_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( - "minecraft:mossy_stone_bricks", + "mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 121, 105), }, ), ( - "minecraft:moving_piston", + "moving_piston", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:mud", + "mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(60, 57, 60), }, ), ( - "minecraft:mud_brick_slab", + "mud_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 103, 79), }, ), ( - "minecraft:mud_brick_stairs", + "mud_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 103, 79), }, ), ( - "minecraft:mud_brick_wall", + "mud_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 103, 79), }, ), ( - "minecraft:mud_bricks", + "mud_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 103, 79), }, ), ( - "minecraft:muddy_mangrove_roots", + "muddy_mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(70, 58, 45), }, ), ( - "minecraft:mushroom_stem", + "mushroom_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(203, 196, 185), }, ), ( - "minecraft:mycelium", + "mycelium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 98, 101), }, ), ( - "minecraft:nether_brick_fence", + "nether_brick_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( - "minecraft:nether_brick_slab", + "nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( - "minecraft:nether_brick_stairs", + "nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( - "minecraft:nether_brick_wall", + "nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( - "minecraft:nether_bricks", + "nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 21, 26), }, ), ( - "minecraft:nether_gold_ore", + "nether_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 54, 42), }, ), ( - "minecraft:nether_portal", + "nether_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 11, 192), }, ), ( - "minecraft:nether_quartz_ore", + "nether_quartz_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(117, 65, 62), }, ), ( - "minecraft:nether_sprouts", + "nether_sprouts", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(19, 151, 133), }, ), ( - "minecraft:nether_wart", + "nether_wart", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 18, 19), }, ), ( - "minecraft:nether_wart_block", + "nether_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 2, 2), }, ), ( - "minecraft:netherite_block", + "netherite_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(66, 61, 63), }, ), ( - "minecraft:netherrack", + "netherrack", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(97, 38, 38), }, ), ( - "minecraft:note_block", + "note_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 58, 40), }, ), ( - "minecraft:oak_button", + "oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:oak_door", + "oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 110, 66), }, ), ( - "minecraft:oak_fence", + "oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_fence_gate", + "oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_leaves", + "oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), color: BlockColor(144, 144, 144), }, ), ( - "minecraft:oak_log", + "oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(151, 121, 73), }, ), ( - "minecraft:oak_planks", + "oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_pressure_plate", + "oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_sapling", + "oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 106, 40), }, ), ( - "minecraft:oak_sign", + "oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_slab", + "oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_stairs", + "oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:oak_trapdoor", + "oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(124, 99, 56), }, ), ( - "minecraft:oak_wall_sign", + "oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:oak_wood", + "oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 85, 50), }, ), ( - "minecraft:observer", + "observer", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(98, 98, 98), }, ), ( - "minecraft:obsidian", + "obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 10, 24), }, ), ( - "minecraft:ochre_froglight", + "ochre_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(250, 245, 206), }, ), ( - "minecraft:orange_banner", + "orange_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:orange_bed", + "orange_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:orange_candle", + "orange_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:orange_candle_cake", + "orange_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:orange_carpet", + "orange_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 118, 19), }, ), ( - "minecraft:orange_concrete", + "orange_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(224, 97, 0), }, ), ( - "minecraft:orange_concrete_powder", + "orange_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(227, 131, 31), }, ), ( - "minecraft:orange_glazed_terracotta", + "orange_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 147, 91), }, ), ( - "minecraft:orange_shulker_box", + "orange_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 106, 8), }, ), ( - "minecraft:orange_stained_glass", + "orange_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 127, 51), }, ), ( - "minecraft:orange_stained_glass_pane", + "orange_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(208, 122, 48), }, ), ( - "minecraft:orange_terracotta", + "orange_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 83, 37), }, ), ( - "minecraft:orange_tulip", + "orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:orange_wall_banner", + "orange_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:orange_wool", + "orange_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 118, 19), }, ), ( - "minecraft:oxeye_daisy", + "oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:oxidized_copper", + "oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(82, 162, 132), }, ), ( - "minecraft:oxidized_cut_copper", + "oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:oxidized_cut_copper_slab", + "oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:oxidized_cut_copper_stairs", + "oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:packed_ice", + "packed_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(141, 180, 250), }, ), ( - "minecraft:packed_mud", + "packed_mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 106, 79), }, ), ( - "minecraft:pearlescent_froglight", + "pearlescent_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(245, 240, 239), }, ), ( - "minecraft:peony", + "peony", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 126, 139), }, ), ( - "minecraft:petrified_oak_slab", + "petrified_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:pink_banner", + "pink_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:pink_bed", + "pink_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:pink_candle", + "pink_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:pink_candle_cake", + "pink_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:pink_carpet", + "pink_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(237, 141, 172), }, ), ( - "minecraft:pink_concrete", + "pink_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(213, 101, 142), }, ), ( - "minecraft:pink_concrete_powder", + "pink_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 153, 181), }, ), ( - "minecraft:pink_glazed_terracotta", + "pink_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 154, 181), }, ), ( - "minecraft:pink_shulker_box", + "pink_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(230, 121, 157), }, ), ( - "minecraft:pink_stained_glass", + "pink_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(242, 127, 165), }, ), ( - "minecraft:pink_stained_glass_pane", + "pink_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 122, 159), }, ), ( - "minecraft:pink_terracotta", + "pink_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 78, 78), }, ), ( - "minecraft:pink_tulip", + "pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:pink_wall_banner", + "pink_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:pink_wool", + "pink_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(237, 141, 172), }, ), ( - "minecraft:piston", + "piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 104, 96), }, ), ( - "minecraft:piston_head", + "piston_head", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 127, 85), }, ), ( - "minecraft:player_head", + "player_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:player_wall_head", + "player_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:podzol", + "podzol", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(91, 63, 24), }, ), ( - "minecraft:pointed_dripstone", + "pointed_dripstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 102, 89), }, ), ( - "minecraft:polished_andesite", + "polished_andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( - "minecraft:polished_andesite_slab", + "polished_andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( - "minecraft:polished_andesite_stairs", + "polished_andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 134, 133), }, ), ( - "minecraft:polished_basalt", + "polished_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 98, 100), }, ), ( - "minecraft:polished_blackstone", + "polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:polished_blackstone_brick_slab", + "polished_blackstone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( - "minecraft:polished_blackstone_brick_stairs", + "polished_blackstone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( - "minecraft:polished_blackstone_brick_wall", + "polished_blackstone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( - "minecraft:polished_blackstone_bricks", + "polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(48, 42, 49), }, ), ( - "minecraft:polished_blackstone_button", + "polished_blackstone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:polished_blackstone_pressure_plate", + "polished_blackstone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:polished_blackstone_slab", + "polished_blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:polished_blackstone_stairs", + "polished_blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:polished_blackstone_wall", + "polished_blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 48, 56), }, ), ( - "minecraft:polished_deepslate", + "polished_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( - "minecraft:polished_deepslate_slab", + "polished_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( - "minecraft:polished_deepslate_stairs", + "polished_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( - "minecraft:polished_deepslate_wall", + "polished_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 73), }, ), ( - "minecraft:polished_diorite", + "polished_diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( - "minecraft:polished_diorite_slab", + "polished_diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( - "minecraft:polished_diorite_stairs", + "polished_diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 193, 194), }, ), ( - "minecraft:polished_granite", + "polished_granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( - "minecraft:polished_granite_slab", + "polished_granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( - "minecraft:polished_granite_stairs", + "polished_granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 106, 89), }, ), ( - "minecraft:poppy", + "poppy", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:potatoes", + "potatoes", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(84, 135, 47), }, ), ( - "minecraft:potted_acacia_sapling", + "potted_acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 117, 23), }, ), ( - "minecraft:potted_allium", + "potted_allium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 137, 183), }, ), ( - "minecraft:potted_azalea_bush", + "potted_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(101, 124, 47), }, ), ( - "minecraft:potted_azure_bluet", + "potted_azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 204, 127), }, ), ( - "minecraft:potted_bamboo", + "potted_bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 144, 19), }, ), ( - "minecraft:potted_birch_sapling", + "potted_birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 160, 79), }, ), ( - "minecraft:potted_blue_orchid", + "potted_blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 162, 168), }, ), ( - "minecraft:potted_brown_mushroom", + "potted_brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 116, 92), }, ), ( - "minecraft:potted_cactus", + "potted_cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 127, 43), }, ), ( - "minecraft:potted_cornflower", + "potted_cornflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 121, 146), }, ), ( - "minecraft:potted_crimson_fungus", + "potted_crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(141, 44, 29), }, ), ( - "minecraft:potted_crimson_roots", + "potted_crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 8, 41), }, ), ( - "minecraft:potted_dandelion", + "potted_dandelion", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 172, 43), }, ), ( - "minecraft:potted_dark_oak_sapling", + "potted_dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(61, 90, 30), }, ), ( - "minecraft:potted_dead_bush", + "potted_dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(107, 78, 40), }, ), ( - "minecraft:potted_fern", + "potted_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(124, 124, 124), }, ), ( - "minecraft:potted_flowering_azalea_bush", + "potted_flowering_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(112, 121, 64), }, ), ( - "minecraft:potted_jungle_sapling", + "potted_jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 81, 16), }, ), ( - "minecraft:potted_lily_of_the_valley", + "potted_lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 174, 95), }, ), ( - "minecraft:potted_mangrove_propagule", + "potted_mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(96, 174, 83), }, ), ( - "minecraft:potted_oak_sapling", + "potted_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(77, 106, 40), }, ), ( - "minecraft:potted_orange_tulip", + "potted_orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 142, 30), }, ), ( - "minecraft:potted_oxeye_daisy", + "potted_oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(179, 202, 143), }, ), ( - "minecraft:potted_pink_tulip", + "potted_pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 157, 78), }, ), ( - "minecraft:potted_poppy", + "potted_poppy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(128, 64, 37), }, ), ( - "minecraft:potted_red_mushroom", + "potted_red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(216, 75, 67), }, ), ( - "minecraft:potted_red_tulip", + "potted_red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(89, 128, 32), }, ), ( - "minecraft:potted_spruce_sapling", + "potted_spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 60, 36), }, ), ( - "minecraft:potted_warped_fungus", + "potted_warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(74, 109, 87), }, ), ( - "minecraft:potted_warped_roots", + "potted_warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 136, 123), }, ), ( - "minecraft:potted_white_tulip", + "potted_white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(93, 164, 71), }, ), ( - "minecraft:potted_wither_rose", + "potted_wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(41, 44, 23), }, ), ( - "minecraft:powder_snow", + "powder_snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 253, 253), }, ), ( - "minecraft:powder_snow_cauldron", + "powder_snow_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( - "minecraft:powered_rail", + "powered_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 109, 74), }, ), ( - "minecraft:prismarine", + "prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( - "minecraft:prismarine_brick_slab", + "prismarine_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( - "minecraft:prismarine_brick_stairs", + "prismarine_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( - "minecraft:prismarine_bricks", + "prismarine_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 171, 158), }, ), ( - "minecraft:prismarine_slab", + "prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( - "minecraft:prismarine_stairs", + "prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( - "minecraft:prismarine_wall", + "prismarine_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(99, 156, 151), }, ), ( - "minecraft:pumpkin", + "pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(198, 118, 24), }, ), ( - "minecraft:pumpkin_stem", + "pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(154, 154, 154), }, ), ( - "minecraft:purple_banner", + "purple_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:purple_bed", + "purple_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:purple_candle", + "purple_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:purple_candle_cake", + "purple_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:purple_carpet", + "purple_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 42, 172), }, ), ( - "minecraft:purple_concrete", + "purple_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(100, 31, 156), }, ), ( - "minecraft:purple_concrete_powder", + "purple_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 55, 177), }, ), ( - "minecraft:purple_glazed_terracotta", + "purple_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 48, 152), }, ), ( - "minecraft:purple_shulker_box", + "purple_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 32, 156), }, ), ( - "minecraft:purple_stained_glass", + "purple_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(127, 63, 178), }, ), ( - "minecraft:purple_stained_glass_pane", + "purple_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 61, 171), }, ), ( - "minecraft:purple_terracotta", + "purple_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(118, 70, 86), }, ), ( - "minecraft:purple_wall_banner", + "purple_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:purple_wool", + "purple_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 42, 172), }, ), ( - "minecraft:purpur_block", + "purpur_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( - "minecraft:purpur_pillar", + "purpur_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 129, 171), }, ), ( - "minecraft:purpur_slab", + "purpur_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( - "minecraft:purpur_stairs", + "purpur_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(169, 125, 169), }, ), ( - "minecraft:quartz_block", + "quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:quartz_bricks", + "quartz_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 229, 221), }, ), ( - "minecraft:quartz_pillar", + "quartz_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 230, 224), }, ), ( - "minecraft:quartz_slab", + "quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:quartz_stairs", + "quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:rail", + "rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 111, 88), }, ), ( - "minecraft:raw_copper_block", + "raw_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 105, 79), }, ), ( - "minecraft:raw_gold_block", + "raw_gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(221, 169, 46), }, ), ( - "minecraft:raw_iron_block", + "raw_iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 135, 107), }, ), ( - "minecraft:red_banner", + "red_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_bed", + "red_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_candle", + "red_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_candle_cake", + "red_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:red_carpet", + "red_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 39, 34), }, ), ( - "minecraft:red_concrete", + "red_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 32, 32), }, ), ( - "minecraft:red_concrete_powder", + "red_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(168, 54, 50), }, ), ( - "minecraft:red_glazed_terracotta", + "red_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 59, 53), }, ), ( - "minecraft:red_mushroom", + "red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_mushroom_block", + "red_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(200, 46, 45), }, ), ( - "minecraft:red_nether_brick_slab", + "red_nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( - "minecraft:red_nether_brick_stairs", + "red_nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( - "minecraft:red_nether_brick_wall", + "red_nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( - "minecraft:red_nether_bricks", + "red_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(69, 7, 9), }, ), ( - "minecraft:red_sand", + "red_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(190, 102, 33), }, ), ( - "minecraft:red_sandstone", + "red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:red_sandstone_slab", + "red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:red_sandstone_stairs", + "red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:red_sandstone_wall", + "red_sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:red_shulker_box", + "red_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 31, 30), }, ), ( - "minecraft:red_stained_glass", + "red_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(153, 51, 51), }, ), ( - "minecraft:red_stained_glass_pane", + "red_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(147, 48, 48), }, ), ( - "minecraft:red_terracotta", + "red_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(143, 61, 46), }, ), ( - "minecraft:red_tulip", + "red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_wall_banner", + "red_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:red_wool", + "red_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 39, 34), }, ), ( - "minecraft:redstone_block", + "redstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 24, 5), }, ), ( - "minecraft:redstone_lamp", + "redstone_lamp", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(95, 54, 30), }, ), ( - "minecraft:redstone_ore", + "redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(140, 109, 109), }, ), ( - "minecraft:redstone_torch", + "redstone_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:redstone_wall_torch", + "redstone_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:redstone_wire", + "redstone_wire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(175, 24, 5), }, ), ( - "minecraft:reinforced_deepslate", + "reinforced_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 82, 78), }, ), ( - "minecraft:repeater", + "repeater", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 157, 156), }, ), ( - "minecraft:repeating_command_block", + "repeating_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(129, 111, 176), }, ), ( - "minecraft:respawn_anchor", + "respawn_anchor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 26, 144), }, ), ( - "minecraft:rooted_dirt", + "rooted_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(144, 103, 76), }, ), ( - "minecraft:rose_bush", + "rose_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(131, 66, 37), }, ), ( - "minecraft:sand", + "sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(219, 207, 163), }, ), ( - "minecraft:sandstone", + "sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:sandstone_slab", + "sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:sandstone_stairs", + "sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:sandstone_wall", + "sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:scaffolding", + "scaffolding", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(174, 134, 80), }, ), ( - "minecraft:sculk", + "sculk", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(12, 29, 36), }, ), ( - "minecraft:sculk_catalyst", + "sculk_catalyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(15, 31, 38), }, ), ( - "minecraft:sculk_sensor", + "sculk_sensor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(7, 70, 84), }, ), ( - "minecraft:sculk_shrieker", + "sculk_shrieker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(198, 205, 169), }, ), ( - "minecraft:sculk_vein", + "sculk_vein", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(7, 48, 57), }, ), ( - "minecraft:sea_lantern", + "sea_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(172, 199, 190), }, ), ( - "minecraft:sea_pickle", + "sea_pickle", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(90, 97, 39), }, ), ( - "minecraft:seagrass", + "seagrass", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:shroomlight", + "shroomlight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 146, 70), }, ), ( - "minecraft:shulker_box", + "shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(139, 96, 139), }, ), ( - "minecraft:sign", + "sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:skeleton_skull", + "skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:skeleton_wall_skull", + "skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:slime_block", + "slime_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(111, 192, 91), }, ), ( - "minecraft:small_amethyst_bud", + "small_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:small_dripleaf", + "small_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:smithing_table", + "smithing_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 58, 70), }, ), ( - "minecraft:smoker", + "smoker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(85, 83, 81), }, ), ( - "minecraft:smooth_basalt", + "smooth_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 72, 78), }, ), ( - "minecraft:smooth_quartz", + "smooth_quartz", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:smooth_quartz_slab", + "smooth_quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:smooth_quartz_stairs", + "smooth_quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(235, 229, 222), }, ), ( - "minecraft:smooth_red_sandstone", + "smooth_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:smooth_red_sandstone_slab", + "smooth_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:smooth_red_sandstone_stairs", + "smooth_red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(181, 97, 31), }, ), ( - "minecraft:smooth_sandstone", + "smooth_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:smooth_sandstone_slab", + "smooth_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:smooth_sandstone_stairs", + "smooth_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(223, 214, 170), }, ), ( - "minecraft:smooth_stone", + "smooth_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 158, 158), }, ), ( - "minecraft:smooth_stone_slab", + "smooth_stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(158, 158, 158), }, ), ( - "minecraft:snow", + "snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(249, 254, 254), }, ), ( - "minecraft:snow_block", + "snow_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(249, 254, 254), }, ), ( - "minecraft:soul_campfire", + "soul_campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(80, 204, 208), }, ), ( - "minecraft:soul_fire", + "soul_fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(51, 192, 197), }, ), ( - "minecraft:soul_lantern", + "soul_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(71, 99, 114), }, ), ( - "minecraft:soul_sand", + "soul_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(81, 62, 50), }, ), ( - "minecraft:soul_soil", + "soul_soil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(75, 57, 46), }, ), ( - "minecraft:soul_torch", + "soul_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:soul_wall_torch", + "soul_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:spawner", + "spawner", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(36, 46, 62), }, ), ( - "minecraft:sponge", + "sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(195, 192, 74), }, ), ( - "minecraft:spore_blossom", + "spore_blossom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(206, 96, 158), }, ), ( - "minecraft:spruce_button", + "spruce_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:spruce_door", + "spruce_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(106, 80, 48), }, ), ( - "minecraft:spruce_fence", + "spruce_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_fence_gate", + "spruce_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_leaves", + "spruce_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), color: BlockColor(126, 126, 126), }, ), ( - "minecraft:spruce_log", + "spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 80, 46), }, ), ( - "minecraft:spruce_planks", + "spruce_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_pressure_plate", + "spruce_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_sapling", + "spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 60, 36), }, ), ( - "minecraft:spruce_sign", + "spruce_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_slab", + "spruce_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_stairs", + "spruce_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(114, 84, 48), }, ), ( - "minecraft:spruce_trapdoor", + "spruce_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(103, 79, 47), }, ), ( - "minecraft:spruce_wall_sign", + "spruce_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:spruce_wood", + "spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 37, 16), }, ), ( - "minecraft:sticky_piston", + "sticky_piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 104, 96), }, ), ( - "minecraft:stone", + "stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:stone_brick_slab", + "stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( - "minecraft:stone_brick_stairs", + "stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( - "minecraft:stone_brick_wall", + "stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( - "minecraft:stone_bricks", + "stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(122, 121, 122), }, ), ( - "minecraft:stone_button", + "stone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:stone_pressure_plate", + "stone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:stone_slab", + "stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:stone_stairs", + "stone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(125, 125, 125), }, ), ( - "minecraft:stonecutter", + "stonecutter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(123, 118, 111), }, ), ( - "minecraft:stripped_acacia_log", + "stripped_acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 91, 51), }, ), ( - "minecraft:stripped_acacia_wood", + "stripped_acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(174, 92, 59), }, ), ( - "minecraft:stripped_birch_log", + "stripped_birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 171, 116), }, ), ( - "minecraft:stripped_birch_wood", + "stripped_birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(196, 176, 118), }, ), ( - "minecraft:stripped_crimson_hyphae", + "stripped_crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(137, 57, 90), }, ), ( - "minecraft:stripped_crimson_stem", + "stripped_crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(121, 56, 82), }, ), ( - "minecraft:stripped_dark_oak_log", + "stripped_dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(65, 44, 22), }, ), ( - "minecraft:stripped_dark_oak_wood", + "stripped_dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(72, 56, 36), }, ), ( - "minecraft:stripped_jungle_log", + "stripped_jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(165, 122, 81), }, ), ( - "minecraft:stripped_jungle_wood", + "stripped_jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 132, 84), }, ), ( - "minecraft:stripped_mangrove_log", + "stripped_mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 43, 43), }, ), ( - "minecraft:stripped_mangrove_wood", + "stripped_mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(119, 54, 47), }, ), ( - "minecraft:stripped_oak_log", + "stripped_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(160, 129, 77), }, ), ( - "minecraft:stripped_oak_wood", + "stripped_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(177, 144, 86), }, ), ( - "minecraft:stripped_spruce_log", + "stripped_spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(105, 80, 46), }, ), ( - "minecraft:stripped_spruce_wood", + "stripped_spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(115, 89, 52), }, ), ( - "minecraft:stripped_warped_hyphae", + "stripped_warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(57, 150, 147), }, ), ( - "minecraft:stripped_warped_stem", + "stripped_warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(52, 128, 124), }, ), ( - "minecraft:structure_block", + "structure_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(88, 74, 90), }, ), ( - "minecraft:structure_void", + "structure_void", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:sugar_cane", + "sugar_cane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(148, 192, 101), }, ), ( - "minecraft:sunflower", + "sunflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 196, 54), }, ), ( - "minecraft:sweet_berry_bush", + "sweet_berry_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(68, 77, 50), }, ), ( - "minecraft:tall_grass", + "tall_grass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(151, 149, 151), }, ), ( - "minecraft:tall_seagrass", + "tall_seagrass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(59, 139, 14), }, ), ( - "minecraft:target", + "target", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(226, 170, 157), }, ), ( - "minecraft:terracotta", + "terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(152, 94, 67), }, ), ( - "minecraft:tinted_glass", + "tinted_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 38, 46), }, ), ( - "minecraft:tnt", + "tnt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(142, 62, 53), }, ), ( - "minecraft:torch", + "torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:trapped_chest", + "trapped_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(162, 130, 78), }, ), ( - "minecraft:tripwire", + "tripwire", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:tripwire_hook", + "tripwire_hook", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:tube_coral", + "tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:tube_coral_block", + "tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(49, 87, 206), }, ), ( - "minecraft:tube_coral_fan", + "tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:tube_coral_wall_fan", + "tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:tuff", + "tuff", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 109, 102), }, ), ( - "minecraft:turtle_egg", + "turtle_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(228, 226, 191), }, ), ( - "minecraft:twisting_vines", + "twisting_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 143, 124), }, ), ( - "minecraft:twisting_vines_plant", + "twisting_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 135, 122), }, ), ( - "minecraft:verdant_froglight", + "verdant_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(229, 244, 228), }, ), ( - "minecraft:vine", + "vine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), color: BlockColor(116, 116, 116), }, ), ( - "minecraft:void_air", + "void_air", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:wall_sign", + "wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:wall_torch", + "wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:warped_button", + "warped_button", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:warped_door", + "warped_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(44, 126, 120), }, ), ( - "minecraft:warped_fence", + "warped_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_fence_gate", + "warped_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_fungus", + "warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:warped_hyphae", + "warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(58, 58, 77), }, ), ( - "minecraft:warped_nylium", + "warped_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 114, 101), }, ), ( - "minecraft:warped_planks", + "warped_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_pressure_plate", + "warped_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_roots", + "warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(20, 138, 124), }, ), ( - "minecraft:warped_sign", + "warped_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_slab", + "warped_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_stairs", + "warped_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(43, 104, 99), }, ), ( - "minecraft:warped_stem", + "warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(53, 109, 110), }, ), ( - "minecraft:warped_trapdoor", + "warped_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(47, 119, 111), }, ), ( - "minecraft:warped_wall_sign", + "warped_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:warped_wart_block", + "warped_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(22, 119, 121), }, ), ( - "minecraft:water", + "water", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), color: BlockColor(177, 177, 177), }, ), ( - "minecraft:water_cauldron", + "water_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(73, 72, 74), }, ), ( - "minecraft:waxed_copper_block", + "waxed_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(192, 107, 79), }, ), ( - "minecraft:waxed_cut_copper", + "waxed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:waxed_cut_copper_slab", + "waxed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:waxed_cut_copper_stairs", + "waxed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(191, 106, 80), }, ), ( - "minecraft:waxed_exposed_copper", + "waxed_exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(161, 125, 103), }, ), ( - "minecraft:waxed_exposed_cut_copper", + "waxed_exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:waxed_exposed_cut_copper_slab", + "waxed_exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:waxed_exposed_cut_copper_stairs", + "waxed_exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(154, 121, 101), }, ), ( - "minecraft:waxed_oxidized_copper", + "waxed_oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(82, 162, 132), }, ), ( - "minecraft:waxed_oxidized_cut_copper", + "waxed_oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:waxed_oxidized_cut_copper_slab", + "waxed_oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:waxed_oxidized_cut_copper_stairs", + "waxed_oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(79, 153, 126), }, ), ( - "minecraft:waxed_weathered_copper", + "waxed_weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 153, 110), }, ), ( - "minecraft:waxed_weathered_cut_copper", + "waxed_weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:waxed_weathered_cut_copper_slab", + "waxed_weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:waxed_weathered_cut_copper_stairs", + "waxed_weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:weathered_copper", + "weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(108, 153, 110), }, ), ( - "minecraft:weathered_cut_copper", + "weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:weathered_cut_copper_slab", + "weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:weathered_cut_copper_stairs", + "weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(109, 145, 107), }, ), ( - "minecraft:weeping_vines", + "weeping_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(104, 1, 0), }, ), ( - "minecraft:weeping_vines_plant", + "weeping_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(132, 16, 12), }, ), ( - "minecraft:wet_sponge", + "wet_sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(171, 181, 70), }, ), ( - "minecraft:wheat", + "wheat", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(166, 151, 73), }, ), ( - "minecraft:white_banner", + "white_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:white_bed", + "white_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:white_candle", + "white_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:white_candle_cake", + "white_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:white_carpet", + "white_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 236, 236), }, ), ( - "minecraft:white_concrete", + "white_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(207, 213, 214), }, ), ( - "minecraft:white_concrete_powder", + "white_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(225, 227, 227), }, ), ( - "minecraft:white_glazed_terracotta", + "white_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(188, 212, 202), }, ), ( - "minecraft:white_shulker_box", + "white_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(215, 220, 221), }, ), ( - "minecraft:white_stained_glass", + "white_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(255, 255, 255), }, ), ( - "minecraft:white_stained_glass_pane", + "white_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(246, 246, 246), }, ), ( - "minecraft:white_terracotta", + "white_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(209, 178, 161), }, ), ( - "minecraft:white_tulip", + "white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:white_wall_banner", + "white_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:white_wool", + "white_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(233, 236, 236), }, ), ( - "minecraft:wither_rose", + "wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:wither_skeleton_skull", + "wither_skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:wither_skeleton_wall_skull", + "wither_skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:yellow_banner", + "yellow_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:yellow_bed", + "yellow_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:yellow_candle", + "yellow_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:yellow_candle_cake", + "yellow_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 222, 214), }, ), ( - "minecraft:yellow_carpet", + "yellow_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 197, 39), }, ), ( - "minecraft:yellow_concrete", + "yellow_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(240, 175, 21), }, ), ( - "minecraft:yellow_concrete_powder", + "yellow_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(232, 199, 54), }, ), ( - "minecraft:yellow_glazed_terracotta", + "yellow_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(234, 192, 88), }, ), ( - "minecraft:yellow_shulker_box", + "yellow_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 188, 29), }, ), ( - "minecraft:yellow_stained_glass", + "yellow_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(229, 229, 51), }, ), ( - "minecraft:yellow_stained_glass_pane", + "yellow_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(221, 221, 48), }, ), ( - "minecraft:yellow_terracotta", + "yellow_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(186, 133, 35), }, ), ( - "minecraft:yellow_wall_banner", + "yellow_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:yellow_wool", + "yellow_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), color: BlockColor(248, 197, 39), }, ), ( - "minecraft:zombie_head", + "zombie_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), }, ), ( - "minecraft:zombie_wall_head", + "zombie_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), color: BlockColor(0, 0, 0), diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 3d1dc96..1664d8b 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -58,7 +58,8 @@ pub struct BlockTypeMap(HashMap); impl BlockTypeMap { #[inline] pub fn get(&self, id: &str) -> Option { - self.0.get(id).copied() + let suffix = id.strip_prefix("minecraft:")?; + self.0.get(suffix).copied() } } From 4c2fd6c1a9d89b5ede1a74b53edae8b81b2b7b93 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 22:45:56 +0100 Subject: [PATCH 113/460] resource: rename BlockTypeMap to BlockTypes The block_types() function it turned into a Default implementation. --- src/main.rs | 4 ++-- src/resource/mod.rs | 25 ++++++++++++++----------- src/world/layer.rs | 4 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index 30b3b18..493b54f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,14 +50,14 @@ impl Paths { /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { - block_types: resource::BlockTypeMap, + block_types: resource::BlockTypes, paths: &'a Paths, } impl<'a> RegionProcessor<'a> { fn new(paths: &'a Paths) -> Self { RegionProcessor { - block_types: resource::block_types(), + block_types: resource::BlockTypes::default(), paths, } } diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 1664d8b..ee409e6 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -53,21 +53,24 @@ impl BlockType { } } -pub struct BlockTypeMap(HashMap); +#[derive(Debug)] +pub struct BlockTypes(HashMap); -impl BlockTypeMap { +impl Default for BlockTypes { + fn default() -> Self { + BlockTypes( + block_types::BLOCK_TYPES + .iter() + .map(|(k, v)| (String::from(*k), *v)) + .collect(), + ) + } +} + +impl BlockTypes { #[inline] pub fn get(&self, id: &str) -> Option { let suffix = id.strip_prefix("minecraft:")?; self.0.get(suffix).copied() } } - -pub fn block_types() -> BlockTypeMap { - BlockTypeMap( - block_types::BLOCK_TYPES - .iter() - .map(|(k, v)| (String::from(*k), *v)) - .collect(), - ) -} diff --git a/src/world/layer.rs b/src/world/layer.rs index 2232af8..0039136 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use super::chunk::Chunk; use crate::{ - resource::{BlockFlag, BlockType, BlockTypeMap}, + resource::{BlockFlag, BlockType, BlockTypes}, types::*, }; @@ -92,7 +92,7 @@ pub type BlockInfoArray = LayerBlockArray>; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk, block_types: &BlockTypeMap) -> Result> { +pub fn top_layer(chunk: &Chunk, block_types: &BlockTypes) -> Result> { use BLOCKS_PER_CHUNK as N; let mut done = 0; From 89af4aaee29b6a45f114bbc81f606ce12aa1f1a7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 00:03:39 +0100 Subject: [PATCH 114/460] resource: extend BlockTypes with legacy block type data Allow to directly map from id/data values to BlockType. --- src/resource/mod.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/resource/mod.rs b/src/resource/mod.rs index ee409e6..812a0e7 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -54,16 +54,29 @@ impl BlockType { } #[derive(Debug)] -pub struct BlockTypes(HashMap); +pub struct BlockTypes { + block_type_map: HashMap, + legacy_block_types: Box<[[BlockType; 16]; 256]>, +} impl Default for BlockTypes { fn default() -> Self { - BlockTypes( - block_types::BLOCK_TYPES - .iter() - .map(|(k, v)| (String::from(*k), *v)) - .collect(), - ) + let block_type_map: HashMap<_, _> = block_types::BLOCK_TYPES + .iter() + .map(|(k, v)| (String::from(*k), *v)) + .collect(); + let legacy_block_types = Box::new(LEGACY_BLOCK_TYPES.map(|inner| { + inner.map(|id| { + *id.strip_prefix("minecraft:") + .and_then(|suffix| block_type_map.get(suffix)) + .expect("Unknown legacy block type") + }) + })); + + BlockTypes { + block_type_map, + legacy_block_types, + } } } @@ -71,6 +84,11 @@ impl BlockTypes { #[inline] pub fn get(&self, id: &str) -> Option { let suffix = id.strip_prefix("minecraft:")?; - self.0.get(suffix).copied() + self.block_type_map.get(suffix).copied() + } + + #[inline] + pub fn get_legacy(&self, id: u8, data: u8) -> Option { + Some(self.legacy_block_types[id as usize][data as usize]) } } From f2ab424590c4772c83a7864e8ddd14aebeca6280 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Mar 2023 23:14:57 +0100 Subject: [PATCH 115/460] world: store BlockTypes in section types Prepare for sections returning BlockType data directly instead of block IDs. --- src/main.rs | 2 +- src/world/chunk.rs | 30 ++++++++++++++++++++---------- src/world/section.rs | 21 ++++++++++++++++++--- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 493b54f..c351230 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,7 +75,7 @@ impl<'a> RegionProcessor<'a> { /// Processes a single chunk fn process_chunk(&self, data: world::de::Chunk) -> Result> { - let chunk = world::chunk::Chunk::new(&data)?; + let chunk = world::chunk::Chunk::new(&data, &self.block_types)?; world::layer::top_layer(&chunk, &self.block_types) } diff --git a/src/world/chunk.rs b/src/world/chunk.rs index de0726b..45b3476 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -9,7 +9,7 @@ use super::{ de, section::{BiomesV18, Section, SectionV0, SectionV1_13}, }; -use crate::types::*; +use crate::{resource::BlockTypes, types::*}; /// Chunk data structure wrapping a [de::Chunk] for convenient access to /// block and biome data @@ -67,17 +67,23 @@ pub struct SectionIter<'a> { impl<'a> Chunk<'a> { /// Creates a new [Chunk] from a deserialized [de::Chunk] - pub fn new(data: &'a de::Chunk) -> Result { + pub fn new(data: &'a de::Chunk, block_types: &'a BlockTypes) -> Result { let data_version = data.data_version.unwrap_or_default(); match &data.chunk { - de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections), - de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level), + de::ChunkVariants::V1_18 { sections } => { + Self::new_v1_18(data_version, sections, block_types) + } + de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level, block_types), } } /// [Chunk::new] implementation for Minecraft v1.18+ chunks - fn new_v1_18(data_version: u32, sections: &'a Vec) -> Result { + fn new_v1_18( + data_version: u32, + sections: &'a Vec, + block_types: &'a BlockTypes, + ) -> Result { let mut section_map = BTreeMap::new(); for section in sections { @@ -88,6 +94,7 @@ impl<'a> Chunk<'a> { data_version, section.block_states.data.as_ref(), §ion.block_states.palette, + block_types, ) .with_context(|| format!("Failed to load section at Y={}", section.y))?, BiomesV18::new(section.biomes.data.as_ref(), §ion.biomes.palette) @@ -102,7 +109,11 @@ impl<'a> Chunk<'a> { } /// [Chunk::new] implementation for all pre-1.18 chunk variants - fn new_v0(data_version: u32, level: &'a de::LevelV0) -> Result { + fn new_v0( + data_version: u32, + level: &'a de::LevelV0, + block_types: &'a BlockTypes, + ) -> Result { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new(); @@ -114,15 +125,14 @@ impl<'a> Chunk<'a> { } => { section_map_v1_13.insert( SectionY(section.y.into()), - SectionV1_13::new(data_version, Some(block_states), palette).with_context( - || format!("Failed to load section at Y={}", section.y), - )?, + SectionV1_13::new(data_version, Some(block_states), palette, block_types) + .with_context(|| format!("Failed to load section at Y={}", section.y))?, ); } de::SectionV0Variants::V0 { blocks, data } => { section_map_v0.insert( SectionY(section.y.into()), - SectionV0::new(blocks, data).with_context(|| { + SectionV0::new(blocks, data, block_types).with_context(|| { format!("Failed to load section at Y={}", section.y) })?, ); diff --git a/src/world/section.rs b/src/world/section.rs index d02d1be..9cf733a 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -2,7 +2,10 @@ use anyhow::{bail, Context, Result}; use num_integer::div_rem; use super::de; -use crate::{resource, types::*}; +use crate::{ + resource::{self, BlockTypes}, + types::*, +}; /// Determine the number of bits required for indexing into a palette of a given length /// @@ -65,6 +68,7 @@ impl<'a> BiomesV18<'a> { pub struct SectionV1_13<'a> { block_states: Option<&'a fastnbt::LongArray>, palette: &'a Vec, + _block_types: &'a BlockTypes, bits: u8, aligned_blocks: bool, } @@ -75,6 +79,7 @@ impl<'a> SectionV1_13<'a> { data_version: u32, block_states: Option<&'a fastnbt::LongArray>, palette: &'a Vec, + block_types: &'a BlockTypes, ) -> Result { let aligned_blocks = data_version >= 2529; @@ -95,6 +100,7 @@ impl<'a> SectionV1_13<'a> { Ok(Self { block_states, palette, + _block_types: block_types, bits, aligned_blocks, }) @@ -146,11 +152,16 @@ impl<'a> Section for SectionV1_13<'a> { pub struct SectionV0<'a> { blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray, + _block_types: &'a BlockTypes, } impl<'a> SectionV0<'a> { /// Constructs a new [SectionV0] from deserialized data structures - pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result { + pub fn new( + blocks: &'a fastnbt::ByteArray, + data: &'a fastnbt::ByteArray, + block_types: &'a BlockTypes, + ) -> Result { use BLOCKS_PER_CHUNK as N; if blocks.len() != N * N * N { @@ -160,7 +171,11 @@ impl<'a> SectionV0<'a> { bail!("Invalid section extra data"); } - Ok(SectionV0 { blocks, data }) + Ok(SectionV0 { + blocks, + data, + _block_types: block_types, + }) } } From 5c82b80924d4c2b093ad8b71faffeb7df851c4f0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 00:19:01 +0100 Subject: [PATCH 116/460] world/section: replace block_id_at() method with block_at() Directly return a BlockType, preparing for early lookup of palettes. --- src/main.rs | 2 +- src/world/layer.rs | 8 +++----- src/world/section.rs | 25 +++++++++++++++---------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index c351230..80f2b25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,7 +76,7 @@ impl<'a> RegionProcessor<'a> { /// Processes a single chunk fn process_chunk(&self, data: world::de::Chunk) -> Result> { let chunk = world::chunk::Chunk::new(&data, &self.block_types)?; - world::layer::top_layer(&chunk, &self.block_types) + world::layer::top_layer(&chunk) } fn save_region( diff --git a/src/world/layer.rs b/src/world/layer.rs index 0039136..a5d8383 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use super::chunk::Chunk; use crate::{ - resource::{BlockFlag, BlockType, BlockTypes}, + resource::{BlockFlag, BlockType}, types::*, }; @@ -92,7 +92,7 @@ pub type BlockInfoArray = LayerBlockArray>; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk, block_types: &BlockTypes) -> Result> { +pub fn top_layer(chunk: &Chunk) -> Result> { use BLOCKS_PER_CHUNK as N; let mut done = 0; @@ -109,9 +109,7 @@ pub fn top_layer(chunk: &Chunk, block_types: &BlockTypes) -> Result Option { /// Trait for common functions of [SectionV1_13] and [SectionV0] pub trait Section { - fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str>; + fn block_at(&self, coords: SectionBlockCoords) -> Result>; } /// Minecraft v1.18+ section biome data @@ -68,7 +68,7 @@ impl<'a> BiomesV18<'a> { pub struct SectionV1_13<'a> { block_states: Option<&'a fastnbt::LongArray>, palette: &'a Vec, - _block_types: &'a BlockTypes, + block_types: &'a BlockTypes, bits: u8, aligned_blocks: bool, } @@ -100,7 +100,7 @@ impl<'a> SectionV1_13<'a> { Ok(Self { block_states, palette, - _block_types: block_types, + block_types, bits, aligned_blocks, }) @@ -137,13 +137,18 @@ impl<'a> SectionV1_13<'a> { } impl<'a> Section for SectionV1_13<'a> { - fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); let entry = self .palette .get(index) .context("Palette index out of bounds")?; - Ok(&entry.name) + + let block_type = self.block_types.get(&entry.name); + if block_type.is_none() { + eprintln!("Unknown block type: {}", entry.name); + } + Ok(block_type) } } @@ -152,7 +157,7 @@ impl<'a> Section for SectionV1_13<'a> { pub struct SectionV0<'a> { blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray, - _block_types: &'a BlockTypes, + block_types: &'a BlockTypes, } impl<'a> SectionV0<'a> { @@ -174,13 +179,13 @@ impl<'a> SectionV0<'a> { Ok(SectionV0 { blocks, data, - _block_types: block_types, + block_types, }) } } impl<'a> Section for SectionV0<'a> { - fn block_id_at(&self, coords: SectionBlockCoords) -> Result<&str> { + fn block_at(&self, coords: SectionBlockCoords) -> Result> { let offset = coords.offset(); let block = self.blocks[offset] as u8; @@ -192,6 +197,6 @@ impl<'a> Section for SectionV0<'a> { data_byte & 0xf }; - Ok(resource::LEGACY_BLOCK_TYPES[block as usize][data as usize]) + Ok(self.block_types.get_legacy(block, data)) } } From 04bc3e5d53050cb861117ce4403a751bb08dea12 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 00:37:25 +0100 Subject: [PATCH 117/460] world/section: perform palette lookups early Look up block types for all palette entries once during section construction, rather than on block_at(), reducing the number of HashMap lookups by ~1000. --- src/world/section.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index 471f5d0..8c98a68 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -67,8 +67,7 @@ impl<'a> BiomesV18<'a> { #[derive(Debug)] pub struct SectionV1_13<'a> { block_states: Option<&'a fastnbt::LongArray>, - palette: &'a Vec, - block_types: &'a BlockTypes, + palette: Vec>, bits: u8, aligned_blocks: bool, } @@ -97,10 +96,20 @@ impl<'a> SectionV1_13<'a> { } } + let palette_types = palette + .iter() + .map(|entry| { + let block_type = block_types.get(&entry.name); + if block_type.is_none() { + eprintln!("Unknown block type: {}", entry.name); + } + block_type + }) + .collect(); + Ok(Self { block_states, - palette, - block_types, + palette: palette_types, bits, aligned_blocks, }) @@ -139,16 +148,10 @@ impl<'a> SectionV1_13<'a> { impl<'a> Section for SectionV1_13<'a> { fn block_at(&self, coords: SectionBlockCoords) -> Result> { let index = self.palette_index_at(coords); - let entry = self + Ok(*self .palette .get(index) - .context("Palette index out of bounds")?; - - let block_type = self.block_types.get(&entry.name); - if block_type.is_none() { - eprintln!("Unknown block type: {}", entry.name); - } - Ok(block_type) + .context("Palette index out of bounds")?) } } From ed5fb9a6cfb3f2d3851c1717e4b1a16ea9851410 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 00:41:39 +0100 Subject: [PATCH 118/460] resource: remove LEGACY_BLOCK_TYPES reexport As the array is only used internally now, we can also remove the "minecraft:" prefix from the entries. Signed-off-by: Matthias Schiffer --- src/resource/legacy_block_types.rs | 1046 ++++++++++++++-------------- src/resource/mod.rs | 9 +- 2 files changed, 510 insertions(+), 545 deletions(-) diff --git a/src/resource/legacy_block_types.rs b/src/resource/legacy_block_types.rs index 6dc7305..c5d9462 100644 --- a/src/resource/legacy_block_types.rs +++ b/src/resource/legacy_block_types.rs @@ -4,21 +4,21 @@ const fn simple(id: &str) -> [&str; 16] { ] } -const DEF: &str = "minecraft:air"; +const DEF: &str = "air"; const EMPTY: [&str; 16] = simple(DEF); pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ /* 0 */ - simple("minecraft:air"), + simple("air"), /* 1 */ [ - "minecraft:stone", - "minecraft:granite", - "minecraft:polished_granite", - "minecraft:diorite", - "minecraft:polished_diorite", - "minecraft:andesite", - "minecraft:polished_andesite", + "stone", + "granite", + "polished_granite", + "diorite", + "polished_diorite", + "andesite", + "polished_andesite", DEF, DEF, DEF, @@ -30,12 +30,12 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 2 */ - simple("minecraft:grass_block"), + simple("grass_block"), /* 3 */ [ - "minecraft:dirt", - "minecraft:coarse_dirt", - "minecraft:podzol", + "dirt", + "coarse_dirt", + "podzol", DEF, DEF, DEF, @@ -51,15 +51,15 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 4 */ - simple("minecraft:cobblestone"), + simple("cobblestone"), /* 5 */ [ - "minecraft:oak_planks", - "minecraft:spruce_planks", - "minecraft:birch_planks", - "minecraft:jungle_planks", - "minecraft:acacia_planks", - "minecraft:dark_oak_planks", + "oak_planks", + "spruce_planks", + "birch_planks", + "jungle_planks", + "acacia_planks", + "dark_oak_planks", DEF, DEF, DEF, @@ -73,181 +73,151 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ ], /* 6 */ [ - "minecraft:oak_sapling", - "minecraft:spruce_sapling", - "minecraft:birch_sapling", - "minecraft:jungle_sapling", - "minecraft:acacia_sapling", - "minecraft:dark_oak_sapling", + "oak_sapling", + "spruce_sapling", + "birch_sapling", + "jungle_sapling", + "acacia_sapling", + "dark_oak_sapling", DEF, DEF, - "minecraft:oak_sapling", - "minecraft:spruce_sapling", - "minecraft:birch_sapling", - "minecraft:jungle_sapling", - "minecraft:acacia_sapling", - "minecraft:dark_oak_sapling", + "oak_sapling", + "spruce_sapling", + "birch_sapling", + "jungle_sapling", + "acacia_sapling", + "dark_oak_sapling", DEF, DEF, ], /* 7 */ - simple("minecraft:bedrock"), + simple("bedrock"), /* 8 */ - simple("minecraft:water"), + simple("water"), /* 9 */ - simple("minecraft:water"), + simple("water"), /* 10 */ - simple("minecraft:lava"), + simple("lava"), /* 11 */ - simple("minecraft:lava"), + simple("lava"), /* 12 */ [ - "minecraft:sand", - "minecraft:red_sand", - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, + "sand", "red_sand", DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, ], /* 13 */ - simple("minecraft:gravel"), + simple("gravel"), /* 14 */ - simple("minecraft:gold_ore"), + simple("gold_ore"), /* 15 */ - simple("minecraft:iron_ore"), + simple("iron_ore"), /* 16 */ - simple("minecraft:coal_ore"), + simple("coal_ore"), /* 17 */ [ - "minecraft:oak_log", - "minecraft:spruce_log", - "minecraft:birch_log", - "minecraft:jungle_log", - "minecraft:oak_log", - "minecraft:spruce_log", - "minecraft:birch_log", - "minecraft:jungle_log", - "minecraft:oak_log", - "minecraft:spruce_log", - "minecraft:birch_log", - "minecraft:jungle_log", - "minecraft:oak_log", - "minecraft:spruce_log", - "minecraft:birch_log", - "minecraft:jungle_log", + "oak_log", + "spruce_log", + "birch_log", + "jungle_log", + "oak_log", + "spruce_log", + "birch_log", + "jungle_log", + "oak_log", + "spruce_log", + "birch_log", + "jungle_log", + "oak_log", + "spruce_log", + "birch_log", + "jungle_log", ], /* 18 */ [ - "minecraft:oak_leaves", - "minecraft:spruce_leaves", - "minecraft:birch_leaves", - "minecraft:jungle_leaves", - "minecraft:oak_leaves", - "minecraft:spruce_leaves", - "minecraft:birch_leaves", - "minecraft:jungle_leaves", - "minecraft:oak_leaves", - "minecraft:spruce_leaves", - "minecraft:birch_leaves", - "minecraft:jungle_leaves", - "minecraft:oak_leaves", - "minecraft:spruce_leaves", - "minecraft:birch_leaves", - "minecraft:jungle_leaves", + "oak_leaves", + "spruce_leaves", + "birch_leaves", + "jungle_leaves", + "oak_leaves", + "spruce_leaves", + "birch_leaves", + "jungle_leaves", + "oak_leaves", + "spruce_leaves", + "birch_leaves", + "jungle_leaves", + "oak_leaves", + "spruce_leaves", + "birch_leaves", + "jungle_leaves", ], /* 19 */ - simple("minecraft:sponge"), + simple("sponge"), /* 20 */ - simple("minecraft:glass"), + simple("glass"), /* 21 */ - simple("minecraft:lapis_ore"), + simple("lapis_ore"), /* 22 */ - simple("minecraft:lapis_block"), + simple("lapis_block"), /* 23 */ - simple("minecraft:dispenser"), + simple("dispenser"), /* 24 */ - simple("minecraft:sandstone"), + simple("sandstone"), /* 25 */ - simple("minecraft:note_block"), + simple("note_block"), /* 26 */ EMPTY, // bed /* 27 */ - simple("minecraft:powered_rail"), + simple("powered_rail"), /* 28 */ - simple("minecraft:detector_rail"), + simple("detector_rail"), /* 29 */ - simple("minecraft:sticky_piston"), + simple("sticky_piston"), /* 30 */ - simple("minecraft:cobweb"), + simple("cobweb"), /* 31 */ [ - "minecraft:grass", - "minecraft:fern", - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, - DEF, + "grass", "fern", DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, DEF, ], /* 32 */ - simple("minecraft:dead_bush"), + simple("dead_bush"), /* 33 */ - simple("minecraft:piston"), + simple("piston"), /* 34 */ - simple("minecraft:piston_head"), + simple("piston_head"), /* 35 */ [ - "minecraft:white_wool", - "minecraft:orange_wool", - "minecraft:magenta_wool", - "minecraft:light_blue_wool", - "minecraft:yellow_wool", - "minecraft:lime_wool", - "minecraft:pink_wool", - "minecraft:gray_wool", - "minecraft:light_gray_wool", - "minecraft:cyan_wool", - "minecraft:purple_wool", - "minecraft:blue_wool", - "minecraft:brown_wool", - "minecraft:green_wool", - "minecraft:red_wool", - "minecraft:black_wool", + "white_wool", + "orange_wool", + "magenta_wool", + "light_blue_wool", + "yellow_wool", + "lime_wool", + "pink_wool", + "gray_wool", + "light_gray_wool", + "cyan_wool", + "purple_wool", + "blue_wool", + "brown_wool", + "green_wool", + "red_wool", + "black_wool", ], /* 36 */ - simple("minecraft:moving_piston"), + simple("moving_piston"), /* 37 */ - simple("minecraft:dandelion"), + simple("dandelion"), /* 38 */ [ - "minecraft:poppy", - "minecraft:blue_orchid", - "minecraft:allium", - "minecraft:azure_bluet", - "minecraft:red_tulip", - "minecraft:orange_tulip", - "minecraft:white_tulip", - "minecraft:pink_tulip", - "minecraft:oxeye_daisy", + "poppy", + "blue_orchid", + "allium", + "azure_bluet", + "red_tulip", + "orange_tulip", + "white_tulip", + "pink_tulip", + "oxeye_daisy", DEF, DEF, DEF, @@ -257,23 +227,23 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 39 */ - simple("minecraft:brown_mushroom"), + simple("brown_mushroom"), /* 40 */ - simple("minecraft:red_mushroom"), + simple("red_mushroom"), /* 41 */ - simple("minecraft:gold_block"), + simple("gold_block"), /* 42 */ - simple("minecraft:iron_block"), + simple("iron_block"), /* 43 */ [ - "minecraft:smooth_stone_slab", - "minecraft:sandstone_slab", - "minecraft:oak_slab", - "minecraft:cobblestone_slab", - "minecraft:brick_slab", - "minecraft:stone_brick_slab", - "minecraft:nether_brick_slab", - "minecraft:quartz_slab", + "smooth_stone_slab", + "sandstone_slab", + "oak_slab", + "cobblestone_slab", + "brick_slab", + "stone_brick_slab", + "nether_brick_slab", + "quartz_slab", DEF, DEF, DEF, @@ -285,41 +255,41 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ ], /* 44 */ [ - "minecraft:smooth_stone_slab", - "minecraft:sandstone_slab", - "minecraft:oak_slab", - "minecraft:cobblestone_slab", - "minecraft:brick_slab", - "minecraft:stone_brick_slab", - "minecraft:nether_brick_slab", - "minecraft:quartz_slab", - "minecraft:stone_slab", - "minecraft:sandstone_slab", - "minecraft:oak_slab", - "minecraft:cobblestone_slab", - "minecraft:brick_slab", - "minecraft:stone_brick_slab", - "minecraft:nether_brick_slab", - "minecraft:quartz_slab", + "smooth_stone_slab", + "sandstone_slab", + "oak_slab", + "cobblestone_slab", + "brick_slab", + "stone_brick_slab", + "nether_brick_slab", + "quartz_slab", + "stone_slab", + "sandstone_slab", + "oak_slab", + "cobblestone_slab", + "brick_slab", + "stone_brick_slab", + "nether_brick_slab", + "quartz_slab", ], /* 45 */ - simple("minecraft:bricks"), + simple("bricks"), /* 46 */ - simple("minecraft:tnt"), + simple("tnt"), /* 47 */ - simple("minecraft:bookshelf"), + simple("bookshelf"), /* 48 */ - simple("minecraft:mossy_cobblestone"), + simple("mossy_cobblestone"), /* 49 */ - simple("minecraft:obsidian"), + simple("obsidian"), /* 50 */ [ DEF, - "minecraft:wall_torch", - "minecraft:wall_torch", - "minecraft:wall_torch", - "minecraft:wall_torch", - "minecraft:torch", + "wall_torch", + "wall_torch", + "wall_torch", + "wall_torch", + "torch", DEF, DEF, DEF, @@ -332,61 +302,61 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 51 */ - simple("minecraft:fire"), + simple("fire"), /* 52 */ - simple("minecraft:spawner"), + simple("spawner"), /* 53 */ - simple("minecraft:oak_stairs"), + simple("oak_stairs"), /* 54 */ - simple("minecraft:chest"), + simple("chest"), /* 55 */ - simple("minecraft:redstone_wire"), + simple("redstone_wire"), /* 56 */ - simple("minecraft:diamond_ore"), + simple("diamond_ore"), /* 57 */ - simple("minecraft:diamond_block"), + simple("diamond_block"), /* 58 */ - simple("minecraft:crafting_table"), + simple("crafting_table"), /* 59 */ - simple("minecraft:wheat"), + simple("wheat"), /* 60 */ - simple("minecraft:farmland"), + simple("farmland"), /* 61 */ - simple("minecraft:furnace"), + simple("furnace"), /* 62 */ - simple("minecraft:furnace"), + simple("furnace"), /* 63 */ - simple("minecraft:sign"), + simple("sign"), /* 64 */ - simple("minecraft:oak_door"), + simple("oak_door"), /* 65 */ - simple("minecraft:ladder"), + simple("ladder"), /* 66 */ - simple("minecraft:rail"), + simple("rail"), /* 67 */ - simple("minecraft:cobblestone_stairs"), + simple("cobblestone_stairs"), /* 68 */ - simple("minecraft:wall_sign"), + simple("wall_sign"), /* 69 */ - simple("minecraft:lever"), + simple("lever"), /* 70 */ - simple("minecraft:stone_pressure_plate"), + simple("stone_pressure_plate"), /* 71 */ - simple("minecraft:iron_door"), + simple("iron_door"), /* 72 */ - simple("minecraft:oak_pressure_plate"), + simple("oak_pressure_plate"), /* 73 */ - simple("minecraft:redstone_ore"), + simple("redstone_ore"), /* 74 */ - simple("minecraft:redstone_ore"), + simple("redstone_ore"), /* 75 */ [ DEF, - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_torch", DEF, DEF, DEF, @@ -401,11 +371,11 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ /* 76 */ [ DEF, - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_wall_torch", - "minecraft:redstone_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_wall_torch", + "redstone_torch", DEF, DEF, DEF, @@ -418,70 +388,70 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 77 */ - simple("minecraft:stone_button"), + simple("stone_button"), /* 78 */ - simple("minecraft:snow"), + simple("snow"), /* 79 */ - simple("minecraft:ice"), + simple("ice"), /* 80 */ - simple("minecraft:snow_block"), + simple("snow_block"), /* 81 */ - simple("minecraft:cactus"), + simple("cactus"), /* 82 */ - simple("minecraft:clay"), + simple("clay"), /* 83 */ - simple("minecraft:sugar_cane"), + simple("sugar_cane"), /* 84 */ - simple("minecraft:jukebox"), + simple("jukebox"), /* 85 */ - simple("minecraft:oak_fence"), + simple("oak_fence"), /* 86 */ - simple("minecraft:pumpkin"), + simple("pumpkin"), /* 87 */ - simple("minecraft:netherrack"), + simple("netherrack"), /* 88 */ - simple("minecraft:soul_sand"), + simple("soul_sand"), /* 89 */ - simple("minecraft:glowstone"), + simple("glowstone"), /* 90 */ - simple("minecraft:nether_portal"), + simple("nether_portal"), /* 91 */ - simple("minecraft:pumpkin"), + simple("pumpkin"), /* 92 */ - simple("minecraft:cake"), + simple("cake"), /* 93 */ - simple("minecraft:repeater"), + simple("repeater"), /* 94 */ - simple("minecraft:repeater"), + simple("repeater"), /* 95 */ [ - "minecraft:white_stained_glass", - "minecraft:orange_stained_glass", - "minecraft:magenta_stained_glass", - "minecraft:light_blue_stained_glass", - "minecraft:yellow_stained_glass", - "minecraft:lime_stained_glass", - "minecraft:pink_stained_glass", - "minecraft:gray_stained_glass", - "minecraft:light_gray_stained_glass", - "minecraft:cyan_stained_glass", - "minecraft:purple_stained_glass", - "minecraft:blue_stained_glass", - "minecraft:brown_stained_glass", - "minecraft:green_stained_glass", - "minecraft:red_stained_glass", - "minecraft:black_stained_glass", + "white_stained_glass", + "orange_stained_glass", + "magenta_stained_glass", + "light_blue_stained_glass", + "yellow_stained_glass", + "lime_stained_glass", + "pink_stained_glass", + "gray_stained_glass", + "light_gray_stained_glass", + "cyan_stained_glass", + "purple_stained_glass", + "blue_stained_glass", + "brown_stained_glass", + "green_stained_glass", + "red_stained_glass", + "black_stained_glass", ], /* 96 */ - simple("minecraft:oak_trapdoor"), + simple("oak_trapdoor"), /* 97 */ [ - "minecraft:infested_stone", - "minecraft:infested_cobblestone", - "minecraft:infested_stone_bricks", - "minecraft:infested_mossy_stone_bricks", - "minecraft:infested_cracked_stone_bricks", - "minecraft:infested_chiseled_stone_bricks", + "infested_stone", + "infested_cobblestone", + "infested_stone_bricks", + "infested_mossy_stone_bricks", + "infested_cracked_stone_bricks", + "infested_chiseled_stone_bricks", DEF, DEF, DEF, @@ -495,10 +465,10 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ ], /* 98 */ [ - "minecraft:stone_bricks", - "minecraft:mossy_stone_bricks", - "minecraft:cracked_stone_bricks", - "minecraft:chiseled_stone_bricks", + "stone_bricks", + "mossy_stone_bricks", + "cracked_stone_bricks", + "chiseled_stone_bricks", DEF, DEF, DEF, @@ -513,65 +483,65 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 99 */ - simple("minecraft:brown_mushroom_block"), + simple("brown_mushroom_block"), /* 100 */ - simple("minecraft:red_mushroom_block"), + simple("red_mushroom_block"), /* 101 */ - simple("minecraft:iron_bars"), + simple("iron_bars"), /* 102 */ - simple("minecraft:glass_pane"), + simple("glass_pane"), /* 103 */ - simple("minecraft:melon"), + simple("melon"), /* 104 */ - simple("minecraft:pumpkin_stem"), + simple("pumpkin_stem"), /* 105 */ - simple("minecraft:melon_stem"), + simple("melon_stem"), /* 106 */ - simple("minecraft:vine"), + simple("vine"), /* 107 */ - simple("minecraft:oak_fence_gate"), + simple("oak_fence_gate"), /* 108 */ - simple("minecraft:brick_stairs"), + simple("brick_stairs"), /* 109 */ - simple("minecraft:stone_brick_stairs"), + simple("stone_brick_stairs"), /* 110 */ - simple("minecraft:mycelium"), + simple("mycelium"), /* 111 */ - simple("minecraft:lily_pad"), + simple("lily_pad"), /* 112 */ - simple("minecraft:nether_bricks"), + simple("nether_bricks"), /* 113 */ - simple("minecraft:nether_brick_fence"), + simple("nether_brick_fence"), /* 114 */ - simple("minecraft:nether_brick_stairs"), + simple("nether_brick_stairs"), /* 115 */ - simple("minecraft:nether_wart"), + simple("nether_wart"), /* 116 */ - simple("minecraft:enchanting_table"), + simple("enchanting_table"), /* 117 */ - simple("minecraft:brewing_stand"), + simple("brewing_stand"), /* 118 */ - simple("minecraft:cauldron"), + simple("cauldron"), /* 119 */ - simple("minecraft:end_portal"), + simple("end_portal"), /* 120 */ - simple("minecraft:end_portal_frame"), + simple("end_portal_frame"), /* 121 */ - simple("minecraft:end_stone"), + simple("end_stone"), /* 122 */ - simple("minecraft:dragon_egg"), + simple("dragon_egg"), /* 123 */ - simple("minecraft:redstone_lamp"), + simple("redstone_lamp"), /* 124 */ - simple("minecraft:redstone_lamp"), + simple("redstone_lamp"), /* 125 */ [ - "minecraft:oak_slab", - "minecraft:spruce_slab", - "minecraft:birch_slab", - "minecraft:jungle_slab", - "minecraft:acacia_slab", - "minecraft:dark_oak_slab", + "oak_slab", + "spruce_slab", + "birch_slab", + "jungle_slab", + "acacia_slab", + "dark_oak_slab", DEF, DEF, DEF, @@ -585,51 +555,51 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ ], /* 126 */ [ - "minecraft:oak_slab", - "minecraft:spruce_slab", - "minecraft:birch_slab", - "minecraft:jungle_slab", - "minecraft:acacia_slab", - "minecraft:dark_oak_slab", + "oak_slab", + "spruce_slab", + "birch_slab", + "jungle_slab", + "acacia_slab", + "dark_oak_slab", DEF, DEF, - "minecraft:oak_slab", - "minecraft:spruce_slab", - "minecraft:birch_slab", - "minecraft:jungle_slab", - "minecraft:acacia_slab", - "minecraft:dark_oak_slab", + "oak_slab", + "spruce_slab", + "birch_slab", + "jungle_slab", + "acacia_slab", + "dark_oak_slab", DEF, DEF, ], /* 127 */ - simple("minecraft:cocoa"), + simple("cocoa"), /* 128 */ - simple("minecraft:sandstone_stairs"), + simple("sandstone_stairs"), /* 129 */ - simple("minecraft:emerald_ore"), + simple("emerald_ore"), /* 130 */ - simple("minecraft:ender_chest"), + simple("ender_chest"), /* 131 */ - simple("minecraft:tripwire_hook"), + simple("tripwire_hook"), /* 132 */ - simple("minecraft:tripwire"), + simple("tripwire"), /* 133 */ - simple("minecraft:emerald_block"), + simple("emerald_block"), /* 134 */ - simple("minecraft:spruce_stairs"), + simple("spruce_stairs"), /* 135 */ - simple("minecraft:birch_stairs"), + simple("birch_stairs"), /* 136 */ - simple("minecraft:jungle_stairs"), + simple("jungle_stairs"), /* 137 */ - simple("minecraft:command_block"), + simple("command_block"), /* 138 */ - simple("minecraft:beacon"), + simple("beacon"), /* 139 */ [ - "minecraft:cobblestone_wall", - "minecraft:mossy_cobblestone_wall", + "cobblestone_wall", + "mossy_cobblestone_wall", DEF, DEF, DEF, @@ -646,151 +616,151 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 140 */ - simple("minecraft:flower_pot"), + simple("flower_pot"), /* 141 */ - simple("minecraft:carrots"), + simple("carrots"), /* 142 */ - simple("minecraft:potatoes"), + simple("potatoes"), /* 143 */ EMPTY, /* 144 */ EMPTY, /* 145 */ [ - "minecraft:anvil", - "minecraft:anvil", - "minecraft:anvil", - "minecraft:anvil", - "minecraft:chipped_anvil", - "minecraft:chipped_anvil", - "minecraft:chipped_anvil", - "minecraft:chipped_anvil", - "minecraft:damaged_anvil", - "minecraft:damaged_anvil", - "minecraft:damaged_anvil", - "minecraft:damaged_anvil", + "anvil", + "anvil", + "anvil", + "anvil", + "chipped_anvil", + "chipped_anvil", + "chipped_anvil", + "chipped_anvil", + "damaged_anvil", + "damaged_anvil", + "damaged_anvil", + "damaged_anvil", DEF, DEF, DEF, DEF, ], /* 146 */ - simple("minecraft:trapped_chest"), + simple("trapped_chest"), /* 147 */ - simple("minecraft:light_weighted_pressure_plate"), + simple("light_weighted_pressure_plate"), /* 148 */ - simple("minecraft:heavy_weighted_pressure_plate"), + simple("heavy_weighted_pressure_plate"), /* 149 */ - simple("minecraft:comparator"), + simple("comparator"), /* 150 */ - simple("minecraft:comparator"), + simple("comparator"), /* 151 */ - simple("minecraft:daylight_detector"), + simple("daylight_detector"), /* 152 */ - simple("minecraft:redstone_block"), + simple("redstone_block"), /* 153 */ - simple("minecraft:nether_quartz_ore"), + simple("nether_quartz_ore"), /* 154 */ - simple("minecraft:hopper"), + simple("hopper"), /* 155 */ - simple("minecraft:quartz_block"), + simple("quartz_block"), /* 156 */ - simple("minecraft:quartz_stairs"), + simple("quartz_stairs"), /* 157 */ - simple("minecraft:activator_rail"), + simple("activator_rail"), /* 158 */ - simple("minecraft:dropper"), + simple("dropper"), /* 159 */ [ - "minecraft:white_terracotta", - "minecraft:orange_terracotta", - "minecraft:magenta_terracotta", - "minecraft:light_blue_terracotta", - "minecraft:yellow_terracotta", - "minecraft:lime_terracotta", - "minecraft:pink_terracotta", - "minecraft:gray_terracotta", - "minecraft:light_gray_terracotta", - "minecraft:cyan_terracotta", - "minecraft:purple_terracotta", - "minecraft:blue_terracotta", - "minecraft:brown_terracotta", - "minecraft:green_terracotta", - "minecraft:red_terracotta", - "minecraft:black_terracotta", + "white_terracotta", + "orange_terracotta", + "magenta_terracotta", + "light_blue_terracotta", + "yellow_terracotta", + "lime_terracotta", + "pink_terracotta", + "gray_terracotta", + "light_gray_terracotta", + "cyan_terracotta", + "purple_terracotta", + "blue_terracotta", + "brown_terracotta", + "green_terracotta", + "red_terracotta", + "black_terracotta", ], /* 160 */ [ - "minecraft:white_stained_glass_pane", - "minecraft:orange_stained_glass_pane", - "minecraft:magenta_stained_glass_pane", - "minecraft:light_blue_stained_glass_pane", - "minecraft:yellow_stained_glass_pane", - "minecraft:lime_stained_glass_pane", - "minecraft:pink_stained_glass_pane", - "minecraft:gray_stained_glass_pane", - "minecraft:light_gray_stained_glass_pane", - "minecraft:cyan_stained_glass_pane", - "minecraft:purple_stained_glass_pane", - "minecraft:blue_stained_glass_pane", - "minecraft:brown_stained_glass_pane", - "minecraft:green_stained_glass_pane", - "minecraft:red_stained_glass_pane", - "minecraft:black_stained_glass_pane", + "white_stained_glass_pane", + "orange_stained_glass_pane", + "magenta_stained_glass_pane", + "light_blue_stained_glass_pane", + "yellow_stained_glass_pane", + "lime_stained_glass_pane", + "pink_stained_glass_pane", + "gray_stained_glass_pane", + "light_gray_stained_glass_pane", + "cyan_stained_glass_pane", + "purple_stained_glass_pane", + "blue_stained_glass_pane", + "brown_stained_glass_pane", + "green_stained_glass_pane", + "red_stained_glass_pane", + "black_stained_glass_pane", ], /* 161 */ [ - "minecraft:acacia_leaves", - "minecraft:dark_oak_leaves", + "acacia_leaves", + "dark_oak_leaves", DEF, DEF, - "minecraft:acacia_leaves", - "minecraft:dark_oak_leaves", + "acacia_leaves", + "dark_oak_leaves", DEF, DEF, - "minecraft:acacia_leaves", - "minecraft:dark_oak_leaves", + "acacia_leaves", + "dark_oak_leaves", DEF, DEF, - "minecraft:acacia_leaves", - "minecraft:dark_oak_leaves", + "acacia_leaves", + "dark_oak_leaves", DEF, DEF, ], /* 162 */ [ - "minecraft:acacia_log", - "minecraft:dark_oak_log", + "acacia_log", + "dark_oak_log", DEF, DEF, - "minecraft:acacia_log", - "minecraft:dark_oak_log", + "acacia_log", + "dark_oak_log", DEF, DEF, - "minecraft:acacia_log", - "minecraft:dark_oak_log", + "acacia_log", + "dark_oak_log", DEF, DEF, - "minecraft:acacia_log", - "minecraft:dark_oak_log", + "acacia_log", + "dark_oak_log", DEF, DEF, ], /* 163 */ - simple("minecraft:acacia_stairs"), + simple("acacia_stairs"), /* 164 */ - simple("minecraft:dark_oak_stairs"), + simple("dark_oak_stairs"), /* 165 */ - simple("minecraft:slime_block"), + simple("slime_block"), /* 166 */ - simple("minecraft:barrier"), + simple("barrier"), /* 167 */ - simple("minecraft:iron_trapdoor"), + simple("iron_trapdoor"), /* 168 */ [ - "minecraft:prismarine", - "minecraft:prismarine_bricks", - "minecraft:dark_prismarine", + "prismarine", + "prismarine_bricks", + "dark_prismarine", DEF, DEF, DEF, @@ -806,42 +776,42 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ DEF, ], /* 169 */ - simple("minecraft:sea_lantern"), + simple("sea_lantern"), /* 170 */ - simple("minecraft:hay_block"), + simple("hay_block"), /* 171 */ [ - "minecraft:white_carpet", - "minecraft:orange_carpet", - "minecraft:magenta_carpet", - "minecraft:light_blue_carpet", - "minecraft:yellow_carpet", - "minecraft:lime_carpet", - "minecraft:pink_carpet", - "minecraft:gray_carpet", - "minecraft:light_gray_carpet", - "minecraft:cyan_carpet", - "minecraft:purple_carpet", - "minecraft:blue_carpet", - "minecraft:brown_carpet", - "minecraft:green_carpet", - "minecraft:red_carpet", - "minecraft:black_carpet", + "white_carpet", + "orange_carpet", + "magenta_carpet", + "light_blue_carpet", + "yellow_carpet", + "lime_carpet", + "pink_carpet", + "gray_carpet", + "light_gray_carpet", + "cyan_carpet", + "purple_carpet", + "blue_carpet", + "brown_carpet", + "green_carpet", + "red_carpet", + "black_carpet", ], /* 172 */ - simple("minecraft:terracotta"), + simple("terracotta"), /* 173 */ - simple("minecraft:coal_block"), + simple("coal_block"), /* 174 */ - simple("minecraft:packed_ice"), + simple("packed_ice"), /* 175 */ [ - "minecraft:sunflower", - "minecraft:lilac", - "minecraft:tall_grass", - "minecraft:large_fern", - "minecraft:rose_bush", - "minecraft:peony", + "sunflower", + "lilac", + "tall_grass", + "large_fern", + "rose_bush", + "peony", DEF, DEF, DEF, @@ -858,193 +828,193 @@ pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ /* 177 */ EMPTY, // wall banner /* 178 */ - simple("minecraft:daylight_detector"), + simple("daylight_detector"), /* 179 */ - simple("minecraft:red_sandstone"), + simple("red_sandstone"), /* 180 */ - simple("minecraft:red_sandstone_stairs"), + simple("red_sandstone_stairs"), /* 181 */ - simple("minecraft:red_sandstone_slab"), + simple("red_sandstone_slab"), /* 182 */ - simple("minecraft:red_sandstone_slab"), + simple("red_sandstone_slab"), /* 183 */ - simple("minecraft:spruce_fence_gate"), + simple("spruce_fence_gate"), /* 184 */ - simple("minecraft:birch_fence_gate"), + simple("birch_fence_gate"), /* 185 */ - simple("minecraft:jungle_fence_gate"), + simple("jungle_fence_gate"), /* 186 */ - simple("minecraft:dark_oak_fence_gate"), + simple("dark_oak_fence_gate"), /* 187 */ - simple("minecraft:acacia_fence_gate"), + simple("acacia_fence_gate"), /* 188 */ - simple("minecraft:spruce_fence"), + simple("spruce_fence"), /* 189 */ - simple("minecraft:birch_fence"), + simple("birch_fence"), /* 190 */ - simple("minecraft:jungle_fence"), + simple("jungle_fence"), /* 191 */ - simple("minecraft:dark_oak_fence"), + simple("dark_oak_fence"), /* 192 */ - simple("minecraft:acacia_fence"), + simple("acacia_fence"), /* 193 */ - simple("minecraft:spruce_door"), + simple("spruce_door"), /* 194 */ - simple("minecraft:birch_door"), + simple("birch_door"), /* 195 */ - simple("minecraft:jungle_door"), + simple("jungle_door"), /* 196 */ - simple("minecraft:acacia_door"), + simple("acacia_door"), /* 197 */ - simple("minecraft:dark_oak_door"), + simple("dark_oak_door"), /* 198 */ - simple("minecraft:end_rod"), + simple("end_rod"), /* 199 */ - simple("minecraft:chorus_plant"), + simple("chorus_plant"), /* 200 */ - simple("minecraft:chorus_flower"), + simple("chorus_flower"), /* 201 */ - simple("minecraft:purpur_block"), + simple("purpur_block"), /* 202 */ - simple("minecraft:purpur_pillar"), + simple("purpur_pillar"), /* 203 */ - simple("minecraft:purpur_stairs"), + simple("purpur_stairs"), /* 204 */ - simple("minecraft:purpur_slab"), + simple("purpur_slab"), /* 205 */ - simple("minecraft:purpur_slab"), + simple("purpur_slab"), /* 206 */ - simple("minecraft:end_stone_bricks"), + simple("end_stone_bricks"), /* 207 */ - simple("minecraft:beetroots"), + simple("beetroots"), /* 208 */ - simple("minecraft:grass_path"), + simple("grass_path"), /* 209 */ - simple("minecraft:end_gateway"), + simple("end_gateway"), /* 210 */ - simple("minecraft:repeating_command_block"), + simple("repeating_command_block"), /* 211 */ - simple("minecraft:chain_command_block"), + simple("chain_command_block"), /* 212 */ - simple("minecraft:frosted_ice"), + simple("frosted_ice"), /* 213 */ - simple("minecraft:magma_block"), + simple("magma_block"), /* 214 */ - simple("minecraft:nether_wart_block"), + simple("nether_wart_block"), /* 215 */ - simple("minecraft:red_nether_bricks"), + simple("red_nether_bricks"), /* 216 */ - simple("minecraft:bone_block"), + simple("bone_block"), /* 217 */ - simple("minecraft:structure_void"), + simple("structure_void"), /* 218 */ - simple("minecraft:observer"), + simple("observer"), /* 219 */ - simple("minecraft:white_shulker_box"), + simple("white_shulker_box"), /* 220 */ - simple("minecraft:orange_shulker_box"), + simple("orange_shulker_box"), /* 221 */ - simple("minecraft:magenta_shulker_box"), + simple("magenta_shulker_box"), /* 222 */ - simple("minecraft:light_blue_shulker_box"), + simple("light_blue_shulker_box"), /* 223 */ - simple("minecraft:yellow_shulker_box"), + simple("yellow_shulker_box"), /* 224 */ - simple("minecraft:lime_shulker_box"), + simple("lime_shulker_box"), /* 225 */ - simple("minecraft:pink_shulker_box"), + simple("pink_shulker_box"), /* 226 */ - simple("minecraft:gray_shulker_box"), + simple("gray_shulker_box"), /* 227 */ - simple("minecraft:light_gray_shulker_box"), + simple("light_gray_shulker_box"), /* 228 */ - simple("minecraft:cyan_shulker_box"), + simple("cyan_shulker_box"), /* 229 */ - simple("minecraft:purple_shulker_box"), + simple("purple_shulker_box"), /* 230 */ - simple("minecraft:blue_shulker_box"), + simple("blue_shulker_box"), /* 231 */ - simple("minecraft:brown_shulker_box"), + simple("brown_shulker_box"), /* 232 */ - simple("minecraft:green_shulker_box"), + simple("green_shulker_box"), /* 233 */ - simple("minecraft:red_shulker_box"), + simple("red_shulker_box"), /* 234 */ - simple("minecraft:black_shulker_box"), + simple("black_shulker_box"), /* 235 */ - simple("minecraft:white_glazed_terracotta"), + simple("white_glazed_terracotta"), /* 236 */ - simple("minecraft:orange_glazed_terracotta"), + simple("orange_glazed_terracotta"), /* 237 */ - simple("minecraft:magenta_glazed_terracotta"), + simple("magenta_glazed_terracotta"), /* 238 */ - simple("minecraft:light_blue_glazed_terracotta"), + simple("light_blue_glazed_terracotta"), /* 239 */ - simple("minecraft:yellow_glazed_terracotta"), + simple("yellow_glazed_terracotta"), /* 240 */ - simple("minecraft:lime_glazed_terracotta"), + simple("lime_glazed_terracotta"), /* 241 */ - simple("minecraft:pink_glazed_terracotta"), + simple("pink_glazed_terracotta"), /* 242 */ - simple("minecraft:gray_glazed_terracotta"), + simple("gray_glazed_terracotta"), /* 243 */ - simple("minecraft:light_gray_glazed_terracotta"), + simple("light_gray_glazed_terracotta"), /* 244 */ - simple("minecraft:cyan_glazed_terracotta"), + simple("cyan_glazed_terracotta"), /* 245 */ - simple("minecraft:purple_glazed_terracotta"), + simple("purple_glazed_terracotta"), /* 246 */ - simple("minecraft:blue_glazed_terracotta"), + simple("blue_glazed_terracotta"), /* 247 */ - simple("minecraft:brown_glazed_terracotta"), + simple("brown_glazed_terracotta"), /* 248 */ - simple("minecraft:green_glazed_terracotta"), + simple("green_glazed_terracotta"), /* 249 */ - simple("minecraft:red_glazed_terracotta"), + simple("red_glazed_terracotta"), /* 250 */ - simple("minecraft:black_glazed_terracotta"), + simple("black_glazed_terracotta"), /* 251 */ [ - "minecraft:white_concrete", - "minecraft:orange_concrete", - "minecraft:magenta_concrete", - "minecraft:light_blue_concrete", - "minecraft:yellow_concrete", - "minecraft:lime_concrete", - "minecraft:pink_concrete", - "minecraft:gray_concrete", - "minecraft:light_gray_concrete", - "minecraft:cyan_concrete", - "minecraft:purple_concrete", - "minecraft:blue_concrete", - "minecraft:brown_concrete", - "minecraft:green_concrete", - "minecraft:red_concrete", - "minecraft:black_concrete", + "white_concrete", + "orange_concrete", + "magenta_concrete", + "light_blue_concrete", + "yellow_concrete", + "lime_concrete", + "pink_concrete", + "gray_concrete", + "light_gray_concrete", + "cyan_concrete", + "purple_concrete", + "blue_concrete", + "brown_concrete", + "green_concrete", + "red_concrete", + "black_concrete", ], /* 252 */ [ - "minecraft:white_concrete_powder", - "minecraft:orange_concrete_powder", - "minecraft:magenta_concrete_powder", - "minecraft:light_blue_concrete_powder", - "minecraft:yellow_concrete_powder", - "minecraft:lime_concrete_powder", - "minecraft:pink_concrete_powder", - "minecraft:gray_concrete_powder", - "minecraft:light_gray_concrete_powder", - "minecraft:cyan_concrete_powder", - "minecraft:purple_concrete_powder", - "minecraft:blue_concrete_powder", - "minecraft:brown_concrete_powder", - "minecraft:green_concrete_powder", - "minecraft:red_concrete_powder", - "minecraft:black_concrete_powder", + "white_concrete_powder", + "orange_concrete_powder", + "magenta_concrete_powder", + "light_blue_concrete_powder", + "yellow_concrete_powder", + "lime_concrete_powder", + "pink_concrete_powder", + "gray_concrete_powder", + "light_gray_concrete_powder", + "cyan_concrete_powder", + "purple_concrete_powder", + "blue_concrete_powder", + "brown_concrete_powder", + "green_concrete_powder", + "red_concrete_powder", + "black_concrete_powder", ], /* 253 */ EMPTY, /* 254 */ EMPTY, /* 255 */ - simple("minecraft:structure_block"), + simple("structure_block"), ]; diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 812a0e7..8bad34f 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -5,7 +5,6 @@ use std::collections::HashMap; use enumflags2::{bitflags, BitFlags}; -pub use legacy_block_types::LEGACY_BLOCK_TYPES; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[bitflags] @@ -65,12 +64,8 @@ impl Default for BlockTypes { .iter() .map(|(k, v)| (String::from(*k), *v)) .collect(); - let legacy_block_types = Box::new(LEGACY_BLOCK_TYPES.map(|inner| { - inner.map(|id| { - *id.strip_prefix("minecraft:") - .and_then(|suffix| block_type_map.get(suffix)) - .expect("Unknown legacy block type") - }) + 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")) })); BlockTypes { From 1d4c7a86ffb5c06c2b8bf0782dd81c23e21ee085 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 01:00:55 +0100 Subject: [PATCH 119/460] world/layer: replace iproduct!() with nested loops iproduct!() is slow for more than 2 parameters. --- src/world/layer.rs | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index a5d8383..94bd3e7 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use itertools::iproduct; use serde::{Deserialize, Serialize}; use super::chunk::Chunk; @@ -98,30 +97,30 @@ pub fn top_layer(chunk: &Chunk) -> Result> { let mut done = 0; let mut ret = Box::::default(); - for ((section_y, section), y, xz) in iproduct!( - chunk.sections().rev(), - BlockY::iter().rev(), - BlockInfoArray::keys() - ) { - let entry = &mut ret[xz]; - if entry.done() { - continue; - } + for (section_y, section) in chunk.sections().rev() { + for y in BlockY::iter().rev() { + for xz in BlockInfoArray::keys() { + let entry = &mut ret[xz]; + if entry.done() { + continue; + } - let coords = SectionBlockCoords { xz, y }; - let Some(block_type) = section.block_at(coords)? else { - continue; - }; - let height = BlockHeight::new(section_y, y)?; - if !entry.fill(height, block_type) { - continue; - } + let coords = SectionBlockCoords { xz, y }; + let Some(block_type) = section.block_at(coords)? else { + continue; + }; + let height = BlockHeight::new(section_y, y)?; + if !entry.fill(height, block_type) { + continue; + } - assert!(entry.done()); + assert!(entry.done()); - done += 1; - if done == N * N { - break; + done += 1; + if done == N * N { + break; + } + } } } From ec09afcf15d14514ecafd5833ecdd5b9e4c30294 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2023 01:23:24 +0100 Subject: [PATCH 120/460] main: fully print error messages --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 80f2b25..a3c9105 100644 --- a/src/main.rs +++ b/src/main.rs @@ -155,7 +155,7 @@ impl<'a> RegionProcessor<'a> { if let Err(err) = self.process_region(&path, coords) { eprintln!( - "Failed to process region r.{}.{}.mca: {}", + "Failed to process region r.{}.{}.mca: {:?}", coords.0, coords.1, err, ); } From 2ccb282f6fe4fb5781b76feecbb6d9048f4fb1be Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:02:55 +0100 Subject: [PATCH 121/460] main: rename Paths to Config --- src/main.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index a3c9105..38b9bf5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,19 +18,19 @@ struct Args { type RegionCoords = (i32, i32); -struct Paths { +struct Config { region_dir: PathBuf, processed_dir: PathBuf, map_dir: PathBuf, } -impl Paths { +impl Config { fn new(args: Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); - Paths { + Config { region_dir, processed_dir, map_dir, @@ -51,14 +51,14 @@ impl Paths { /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { block_types: resource::BlockTypes, - paths: &'a Paths, + config: &'a Config, } impl<'a> RegionProcessor<'a> { - fn new(paths: &'a Paths) -> Self { + fn new(config: &'a Config) -> Self { RegionProcessor { block_types: resource::BlockTypes::default(), - paths, + config, } } @@ -84,10 +84,10 @@ impl<'a> RegionProcessor<'a> { region: RegionCoords, processed_data: &ChunkArray>>, ) -> Result<()> { - let tmp_path = self.paths.processed_path(region, true); + let tmp_path = self.config.processed_path(region, true); storage::write(&tmp_path, processed_data)?; - let output_path = self.paths.processed_path(region, false); + let output_path = self.config.processed_path(region, false); fs::rename(&tmp_path, &output_path).with_context(|| { format!( "Failed to rename {} to {}", @@ -125,17 +125,17 @@ impl<'a> RegionProcessor<'a> { /// /// Returns a list of the coordinates of all processed regions fn run(self) -> Result> { - let read_dir = self.paths.region_dir.read_dir().with_context(|| { + let read_dir = self.config.region_dir.read_dir().with_context(|| { format!( "Failed to read directory {}", - self.paths.region_dir.display() + self.config.region_dir.display() ) })?; - fs::create_dir_all(&self.paths.processed_dir).with_context(|| { + fs::create_dir_all(&self.config.processed_dir).with_context(|| { format!( "Failed to create directory {}", - self.paths.processed_dir.display(), + self.config.processed_dir.display(), ) })?; @@ -168,12 +168,12 @@ impl<'a> RegionProcessor<'a> { } struct TileRenderer<'a> { - paths: &'a Paths, + config: &'a Config, } impl<'a> TileRenderer<'a> { - fn new(paths: &'a Paths) -> Self { - TileRenderer { paths } + fn new(config: &'a Config) -> Self { + TileRenderer { config } } fn render_tile(&self, coords: RegionCoords) -> Result<()> { @@ -183,10 +183,10 @@ impl<'a> TileRenderer<'a> { } fn run(self, regions: &[RegionCoords]) -> Result<()> { - fs::create_dir_all(&self.paths.map_dir).with_context(|| { + fs::create_dir_all(&self.config.map_dir).with_context(|| { format!( "Failed to create directory {}", - self.paths.map_dir.display(), + self.config.map_dir.display(), ) })?; @@ -200,10 +200,10 @@ impl<'a> TileRenderer<'a> { fn main() -> Result<()> { let args = Args::parse(); - let paths = Paths::new(args); + let config = Config::new(args); - let regions = RegionProcessor::new(&paths).run()?; - TileRenderer::new(&paths).run(®ions)?; + let regions = RegionProcessor::new(&config).run()?; + TileRenderer::new(&config).run(®ions)?; Ok(()) } From 51a0e178b1aeaab37c7d5560d81db974c7c93eba Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:06:08 +0100 Subject: [PATCH 122/460] main: do not rebuild region filename from coords --- src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 38b9bf5..5c40ffa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -155,8 +155,9 @@ impl<'a> RegionProcessor<'a> { if let Err(err) = self.process_region(&path, coords) { eprintln!( - "Failed to process region r.{}.{}.mca: {:?}", - coords.0, coords.1, err, + "Failed to process region {}: {:?}", + path.file_name().unwrap_or_default().to_string_lossy(), + err, ); } From dda81546dec3dcb83d0e24136fe2e30503bd3cd3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:13:15 +0100 Subject: [PATCH 123/460] main: add map_path() method to Config struct --- src/main.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 5c40ffa..381a0fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,16 @@ impl Config { ); [&self.processed_dir, Path::new(&filename)].iter().collect() } + + fn map_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.png{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.map_dir, Path::new(&filename)].iter().collect() + } } /// Type with methods for processing the regions of a Minecraft save directory @@ -178,7 +188,14 @@ impl<'a> TileRenderer<'a> { } fn render_tile(&self, coords: RegionCoords) -> Result<()> { - println!("Rendering tile r.{}.{}.png", coords.0, coords.1); + let output_path = self.config.map_path(coords, false); + println!( + "Rendering tile {}", + output_path + .file_name() + .unwrap_or_default() + .to_string_lossy(), + ); Ok(()) } From 657d8af8a7311ea521f946254dc62daf5e63f487 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:20:56 +0100 Subject: [PATCH 124/460] io/storage: add read() function --- src/io/storage.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/io/storage.rs b/src/io/storage.rs index 86430b3..10a7eb3 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -1,11 +1,11 @@ use std::{ fs::File, - io::{BufWriter, Write}, + io::{BufReader, BufWriter, Write}, path::Path, }; use anyhow::{Context, Result}; -use serde::Serialize; +use serde::{de::DeserializeOwned, Serialize}; pub fn write(path: &Path, value: &T) -> Result<()> { (|| -> Result<()> { @@ -20,3 +20,13 @@ pub fn write(path: &Path, value: &T) -> Result<()> { })() .with_context(|| format!("Failed to write file {}", path.display())) } + +pub fn read(path: &Path) -> Result { + (|| -> Result { + let file = File::open(path)?; + let reader = BufReader::new(file); + let decompressor = zstd::Decoder::new(reader)?; + Ok(bincode::deserialize_from(decompressor)?) + })() + .with_context(|| format!("Failed to read file {}", path.display())) +} From e0467de0805dbd791873c09f2f21295a47a5bad1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:22:45 +0100 Subject: [PATCH 125/460] main: rename save_region() argument from region to coords For consistency. --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 381a0fd..d1125cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,13 +91,13 @@ impl<'a> RegionProcessor<'a> { fn save_region( &self, - region: RegionCoords, + coords: RegionCoords, processed_data: &ChunkArray>>, ) -> Result<()> { - let tmp_path = self.config.processed_path(region, true); + let tmp_path = self.config.processed_path(coords, true); storage::write(&tmp_path, processed_data)?; - let output_path = self.config.processed_path(region, false); + let output_path = self.config.processed_path(coords, false); fs::rename(&tmp_path, &output_path).with_context(|| { format!( "Failed to rename {} to {}", From 89f35024b72f1a7b1e196f7d23544755d7989e65 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:24:56 +0100 Subject: [PATCH 126/460] main: introduce ProcessedRegion type alias --- src/main.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index d1125cb..073341c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ struct Args { } type RegionCoords = (i32, i32); +type ProcessedRegion = ChunkArray>>; struct Config { region_dir: PathBuf, @@ -89,13 +90,9 @@ impl<'a> RegionProcessor<'a> { world::layer::top_layer(&chunk) } - fn save_region( - &self, - coords: RegionCoords, - processed_data: &ChunkArray>>, - ) -> Result<()> { + fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { let tmp_path = self.config.processed_path(coords, true); - storage::write(&tmp_path, processed_data)?; + storage::write(&tmp_path, processed_region)?; let output_path = self.config.processed_path(coords, false); fs::rename(&tmp_path, &output_path).with_context(|| { @@ -113,20 +110,19 @@ impl<'a> RegionProcessor<'a> { fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { println!("Processing region r.{}.{}.mca", coords.0, coords.1); - let mut processed_data: ChunkArray>> = - Default::default(); + let mut processed_region = ProcessedRegion::default(); minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let processed_chunk = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))?; - processed_data[chunk_coords] = Some(processed_chunk); + processed_region[chunk_coords] = Some(processed_chunk); Ok(()) }, )?; - self.save_region(coords, &processed_data)?; + self.save_region(coords, &processed_region)?; Ok(()) } From d5406851b4ba2dd6ce80bb1aab84f8fd57b4953e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 19:42:56 +0100 Subject: [PATCH 127/460] main: load processed regions from render_tile() --- src/main.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.rs b/src/main.rs index 073341c..21ebc5b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,6 +183,11 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } + fn load_region(&self, coords: RegionCoords) -> Result { + let processed_path = self.config.processed_path(coords, false); + storage::read(&processed_path).context("Failed to load processed region data") + } + fn render_tile(&self, coords: RegionCoords) -> Result<()> { let output_path = self.config.map_path(coords, false); println!( @@ -193,6 +198,8 @@ impl<'a> TileRenderer<'a> { .to_string_lossy(), ); + let _region = self.load_region(coords); + Ok(()) } From e6e1f55fe99852f510b979a16fc1bec0648a42d0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 20:00:03 +0100 Subject: [PATCH 128/460] Use zlib-ng backend for flate2 by default Still allow disabling the feature to avoid the cmake dependency. --- Cargo.lock | 20 ++++++++++++++++++++ Cargo.toml | 4 ++++ TODO.md | 1 - 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5adcd72..1137014 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,15 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "cmake" +version = "0.1.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +dependencies = [ + "cc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -180,6 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", + "libz-ng-sys", "miniz_oxide", ] @@ -241,6 +251,16 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "libz-ng-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4399ae96a9966bf581e726de86969f803a81b7ce795fcd5480e640589457e0f2" +dependencies = [ + "cmake", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index 6f40d32..e719a80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,7 @@ itertools = "0.10.5" num-integer = "0.1.45" serde = "1.0.152" zstd = "0.12.3" + +[features] +default = ["zlib-ng"] +zlib-ng = ["flate2/zlib-ng"] diff --git a/TODO.md b/TODO.md index e6c14f6..cb18d08 100644 --- a/TODO.md +++ b/TODO.md @@ -5,4 +5,3 @@ - To check: - fastnbt borrow - fastnbt from_reader - - flate2 backends From 26555f17457b7ff0f636cee01e2383b5748ba7ca Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 20:35:43 +0100 Subject: [PATCH 129/460] src/world/layer: make BlockInfo fields public There were left private by accident. --- Cargo.lock | 44 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/world/layer.rs | 6 +++--- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1137014..dda9b5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,6 +114,12 @@ dependencies = [ "cc", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "crc32fast" version = "1.3.2" @@ -205,6 +211,20 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "io-lifetimes" version = "1.0.5" @@ -278,6 +298,7 @@ dependencies = [ "enumflags2", "fastnbt", "flate2", + "image", "itertools", "num-integer", "serde", @@ -303,6 +324,17 @@ 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.15" @@ -330,6 +362,18 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + [[package]] name = "proc-macro-error" version = "1.0.4" diff --git a/Cargo.toml b/Cargo.toml index e719a80..9a82052 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ clap = { version = "4.1.4", features = ["derive"] } enumflags2 = "0.7.5" fastnbt = "2.3.2" flate2 = "1.0.25" +image = { version = "0.24.5", default-features = false, features = ["png"] } itertools = "0.10.5" num-integer = "0.1.45" serde = "1.0.152" diff --git a/src/world/layer.rs b/src/world/layer.rs index 94bd3e7..2f9382c 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -27,9 +27,9 @@ impl BlockHeight { #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockInfo { - block_type: BlockType, - y: BlockHeight, - depth: Option, + pub block_type: BlockType, + pub y: BlockHeight, + pub depth: Option, } /// Helper methods for [BlockInfo] From fa04e3e94affaaf9ec31a9b82de7046cdfb1461c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 20:41:08 +0100 Subject: [PATCH 130/460] main: actually render tiles --- src/main.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 21ebc5b..054b659 100644 --- a/src/main.rs +++ b/src/main.rs @@ -188,7 +188,49 @@ impl<'a> TileRenderer<'a> { storage::read(&processed_path).context("Failed to load processed region data") } + fn render_chunk( + image: &mut image::RgbaImage, + coords: ChunkCoords, + chunk: &world::layer::BlockInfoArray, + ) { + const N: u32 = BLOCKS_PER_CHUNK as u32; + + let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { + image::Rgba( + match chunk[LayerBlockCoords { + x: BlockX(x as u8), + z: BlockZ(z as u8), + }] { + Some(block) => { + let c = block.block_type.color; + [c.0, c.1, c.2, 255] + } + None => [0, 0, 0, 0], + }, + ) + }); + image::imageops::overlay( + image, + &chunk_image, + coords.x.0 as i64 * BLOCKS_PER_CHUNK as i64, + coords.z.0 as i64 * BLOCKS_PER_CHUNK as i64, + ); + } + + fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { + for (coords, chunk) in region.iter() { + let Some(chunk) = chunk else { + continue; + }; + + Self::render_chunk(image, coords, chunk); + } + } + fn render_tile(&self, coords: RegionCoords) -> Result<()> { + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let tmp_path = self.config.map_path(coords, true); let output_path = self.config.map_path(coords, false); println!( "Rendering tile {}", @@ -198,7 +240,19 @@ impl<'a> TileRenderer<'a> { .to_string_lossy(), ); - let _region = self.load_region(coords); + let region = self.load_region(coords)?; + let mut image = image::RgbaImage::new(N, N); + Self::render_region(&mut image, ®ion); + image + .save_with_format(&tmp_path, image::ImageFormat::Png) + .context("Failed to save image")?; + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; Ok(()) } @@ -212,7 +266,9 @@ impl<'a> TileRenderer<'a> { })?; for &coords in regions { - self.render_tile(coords)?; + if let Err(err) = self.render_tile(coords) { + eprintln!("Failed to render tile {:?}: {:?}", coords, err,); + } } Ok(()) From a4b726992a620e55fd59c847a66ebff1462f49d6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Mar 2023 20:58:35 +0100 Subject: [PATCH 131/460] io/storage: compress/decompress data in bulk The bulk API is signifiantly faster than the stream API. --- src/io/storage.rs | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/io/storage.rs b/src/io/storage.rs index 10a7eb3..f4b2eed 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -1,6 +1,6 @@ use std::{ fs::File, - io::{BufReader, BufWriter, Write}, + io::{Read, Write}, path::Path, }; @@ -9,13 +9,16 @@ use serde::{de::DeserializeOwned, Serialize}; pub fn write(path: &Path, value: &T) -> Result<()> { (|| -> Result<()> { - let file = File::create(path)?; - let writer = BufWriter::new(file); - let mut compressor = zstd::Encoder::new(writer, 1)?; - bincode::serialize_into(&mut compressor, value)?; - let writer = compressor.finish()?; - let mut file = writer.into_inner()?; + let data = bincode::serialize(value)?; + let len = u32::try_from(data.len())?; + let compressed = zstd::bulk::compress(&data, 1)?; + drop(data); + + let mut file = File::create(path)?; + file.write_all(&len.to_be_bytes())?; + file.write_all(&compressed)?; file.flush()?; + Ok(()) })() .with_context(|| format!("Failed to write file {}", path.display())) @@ -23,10 +26,18 @@ pub fn write(path: &Path, value: &T) -> Result<()> { pub fn read(path: &Path) -> Result { (|| -> Result { - let file = File::open(path)?; - let reader = BufReader::new(file); - let decompressor = zstd::Decoder::new(reader)?; - Ok(bincode::deserialize_from(decompressor)?) + 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)?) })() .with_context(|| format!("Failed to read file {}", path.display())) } From 56573640fd8873712c4a15a505a9e45908e1db87 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 00:27:26 +0100 Subject: [PATCH 132/460] world/section: prefer slice references to Vec and fastnbt types Makes the code a bit nicer and saves repeated deref calls into fastnbt. --- src/world/chunk.rs | 4 ++-- src/world/section.rs | 22 +++++++++------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 45b3476..3f37210 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -92,12 +92,12 @@ impl<'a> Chunk<'a> { ( SectionV1_13::new( data_version, - section.block_states.data.as_ref(), + section.block_states.data.as_deref(), §ion.block_states.palette, block_types, ) .with_context(|| format!("Failed to load section at Y={}", section.y))?, - BiomesV18::new(section.biomes.data.as_ref(), §ion.biomes.palette) + BiomesV18::new(section.biomes.data.as_deref(), §ion.biomes.palette) .with_context(|| { format!("Failed to load section biomes at Y={}", section.y) })?, diff --git a/src/world/section.rs b/src/world/section.rs index 8c98a68..819bd3f 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -37,14 +37,14 @@ pub trait Section { /// v1.13+ block data. #[derive(Debug)] pub struct BiomesV18<'a> { - _biomes: Option<&'a fastnbt::LongArray>, - _palette: &'a Vec, + _biomes: Option<&'a [i64]>, + _palette: &'a [String], _bits: u8, } impl<'a> BiomesV18<'a> { /// Constructs a new [BiomesV18] from deserialized data structures - pub fn new(biomes: Option<&'a fastnbt::LongArray>, palette: &'a Vec) -> Result { + pub fn new(biomes: Option<&'a [i64]>, palette: &'a [String]) -> Result { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; if let Some(biomes) = biomes { @@ -66,7 +66,7 @@ impl<'a> BiomesV18<'a> { /// Minecraft v1.13+ section block data #[derive(Debug)] pub struct SectionV1_13<'a> { - block_states: Option<&'a fastnbt::LongArray>, + block_states: Option<&'a [i64]>, palette: Vec>, bits: u8, aligned_blocks: bool, @@ -76,8 +76,8 @@ impl<'a> SectionV1_13<'a> { /// Constructs a new [SectionV1_13] from deserialized data structures pub fn new( data_version: u32, - block_states: Option<&'a fastnbt::LongArray>, - palette: &'a Vec, + block_states: Option<&'a [i64]>, + palette: &'a [de::BlockStatePaletteEntry], block_types: &'a BlockTypes, ) -> Result { let aligned_blocks = data_version >= 2529; @@ -158,18 +158,14 @@ impl<'a> Section for SectionV1_13<'a> { /// Pre-1.13 section block data #[derive(Debug)] pub struct SectionV0<'a> { - blocks: &'a fastnbt::ByteArray, - data: &'a fastnbt::ByteArray, + blocks: &'a [i8], + data: &'a [i8], block_types: &'a BlockTypes, } impl<'a> SectionV0<'a> { /// Constructs a new [SectionV0] from deserialized data structures - pub fn new( - blocks: &'a fastnbt::ByteArray, - data: &'a fastnbt::ByteArray, - block_types: &'a BlockTypes, - ) -> Result { + pub fn new(blocks: &'a [i8], data: &'a [i8], block_types: &'a BlockTypes) -> Result { use BLOCKS_PER_CHUNK as N; if blocks.len() != N * N * N { From ed422be451d878551d09e18caaebe4bdcd4d61a7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 11:39:47 +0100 Subject: [PATCH 133/460] TODO.md: update - fastnbt decode doesn't really appear in profiles, so optimizing it using borrowed types is moot - What does appear prominently in the profile though is top_layer() and block_at() --- TODO.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index cb18d08..c4c0668 100644 --- a/TODO.md +++ b/TODO.md @@ -3,5 +3,4 @@ ## Optimizations - To check: - - fastnbt borrow - - fastnbt from_reader + - Bulk `block_at()`, possibly other `top_layer()` improvements From 47dc3795a3c57a0c26dad824caba679e71046e83 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 16:53:53 +0100 Subject: [PATCH 134/460] world: introduce SectionIterItem struct --- src/world/chunk.rs | 26 +++++++++++++++----------- src/world/layer.rs | 8 ++++++-- src/world/section.rs | 4 +++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 3f37210..72c5f9a 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -182,16 +182,19 @@ impl<'a> Chunk<'a> { } } +#[derive(Debug, Clone, Copy)] +pub struct SectionIterItem<'a> { + pub y: SectionY, + pub section: &'a dyn Section, +} + trait SectionIterTrait<'a>: - Iterator - + DoubleEndedIterator - + ExactSizeIterator - + FusedIterator + Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { } impl<'a, T> SectionIterTrait<'a> for T where - T: Iterator + T: Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator @@ -204,14 +207,15 @@ impl<'a> SectionIter<'a> { F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T, { match &mut self.inner { - SectionIterInner::V1_18 { iter } => f( - &mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, §ion.0) }) - ), + SectionIterInner::V1_18 { iter } => f(&mut iter.map(|(&y, section)| SectionIterItem { + y, + section: §ion.0, + })), SectionIterInner::V1_13 { iter } => { - f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) + f(&mut iter.map(|(&y, section)| SectionIterItem { y, section })) } SectionIterInner::V0 { iter } => { - f(&mut iter.map(|(y, section)| -> (SectionY, &'a dyn Section) { (*y, section) })) + f(&mut iter.map(|(&y, section)| SectionIterItem { y, section })) } SectionIterInner::Empty => f(&mut iter::empty()), } @@ -219,7 +223,7 @@ impl<'a> SectionIter<'a> { } impl<'a> Iterator for SectionIter<'a> { - type Item = (SectionY, &'a dyn Section); + type Item = SectionIterItem<'a>; fn next(&mut self) -> Option { self.with_iter(|iter| iter.next()) diff --git a/src/world/layer.rs b/src/world/layer.rs index 2f9382c..5541e34 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; -use super::chunk::Chunk; +use super::chunk::{Chunk, SectionIterItem}; use crate::{ resource::{BlockFlag, BlockType}, types::*, @@ -97,7 +97,11 @@ pub fn top_layer(chunk: &Chunk) -> Result> { let mut done = 0; let mut ret = Box::::default(); - for (section_y, section) in chunk.sections().rev() { + for SectionIterItem { + y: section_y, + section, + } in chunk.sections().rev() + { for y in BlockY::iter().rev() { for xz in BlockInfoArray::keys() { let entry = &mut ret[xz]; diff --git a/src/world/section.rs b/src/world/section.rs index 819bd3f..8a7a8d7 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use anyhow::{bail, Context, Result}; use num_integer::div_rem; @@ -26,7 +28,7 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option { } /// Trait for common functions of [SectionV1_13] and [SectionV0] -pub trait Section { +pub trait Section: Debug { fn block_at(&self, coords: SectionBlockCoords) -> Result>; } From 66f8d155f5f0ce9b77ca9ba0a240c01dacdd275a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 16:58:52 +0100 Subject: [PATCH 135/460] world/section: reorder type definitions --- src/world/section.rs | 66 ++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index 8a7a8d7..aa3c268 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -32,39 +32,6 @@ pub trait Section: Debug { fn block_at(&self, coords: SectionBlockCoords) -> Result>; } -/// Minecraft v1.18+ section biome data -/// -/// The biome data is part of the section structure in Minecraft v1.18+, with -/// the biomes laid out as an array of indices into a palette, similar to the -/// v1.13+ block data. -#[derive(Debug)] -pub struct BiomesV18<'a> { - _biomes: Option<&'a [i64]>, - _palette: &'a [String], - _bits: u8, -} - -impl<'a> BiomesV18<'a> { - /// Constructs a new [BiomesV18] from deserialized data structures - pub fn new(biomes: Option<&'a [i64]>, palette: &'a [String]) -> Result { - let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; - - if let Some(biomes) = biomes { - let biomes_per_word = 64 / bits as usize; - let expected_length = (64 + biomes_per_word - 1) / biomes_per_word; - if biomes.len() != expected_length { - bail!("Invalid section biome data"); - } - } - - Ok(BiomesV18 { - _biomes: biomes, - _palette: palette, - _bits: bits, - }) - } -} - /// Minecraft v1.13+ section block data #[derive(Debug)] pub struct SectionV1_13<'a> { @@ -201,3 +168,36 @@ impl<'a> Section for SectionV0<'a> { Ok(self.block_types.get_legacy(block, data)) } } + +/// Minecraft v1.18+ section biome data +/// +/// The biome data is part of the section structure in Minecraft v1.18+, with +/// the biomes laid out as an array of indices into a palette, similar to the +/// v1.13+ block data. +#[derive(Debug)] +pub struct BiomesV18<'a> { + _biomes: Option<&'a [i64]>, + _palette: &'a [String], + _bits: u8, +} + +impl<'a> BiomesV18<'a> { + /// Constructs a new [BiomesV18] from deserialized data structures + pub fn new(biomes: Option<&'a [i64]>, palette: &'a [String]) -> Result { + let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; + + if let Some(biomes) = biomes { + let biomes_per_word = 64 / bits as usize; + let expected_length = (64 + biomes_per_word - 1) / biomes_per_word; + if biomes.len() != expected_length { + bail!("Invalid section biome data"); + } + } + + Ok(BiomesV18 { + _biomes: biomes, + _palette: palette, + _bits: bits, + }) + } +} From b4eb0d39f91e6a978acc5922e8d08c3cc05548f8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 17:03:22 +0100 Subject: [PATCH 136/460] world/section: add BlockLight type --- src/world/section.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/world/section.rs b/src/world/section.rs index aa3c268..d3c590a 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -201,3 +201,33 @@ impl<'a> BiomesV18<'a> { }) } } + +#[derive(Debug, Clone, Copy)] +pub struct BlockLight<'a>(Option<&'a [i8]>); + +impl<'a> BlockLight<'a> { + pub fn new(block_light: Option<&'a [i8]>) -> Result { + use BLOCKS_PER_CHUNK as N; + if let Some(block_light) = block_light { + if block_light.len() != N * N * N / 2 { + bail!("Invalid section block light data"); + } + } + Ok(BlockLight(block_light)) + } + + pub fn block_light_at(&self, coords: SectionBlockCoords) -> u8 { + let Some(block_light) = self.0 else { + return 0; + }; + + let (offset, nibble) = div_rem(coords.offset(), 2); + let byte = block_light[offset] as u8; + + if nibble == 1 { + byte >> 4 + } else { + byte & 0xf + } + } +} From 482471492cf2622eb656fb272bf49728e4d4ccdf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 17:15:03 +0100 Subject: [PATCH 137/460] world/chunk: store BlockLight data in section map --- src/world/chunk.rs | 58 +++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 72c5f9a..6895ea7 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -5,10 +5,7 @@ use std::{ use anyhow::{bail, Context, Result}; -use super::{ - de, - section::{BiomesV18, Section, SectionV0, SectionV1_13}, -}; +use super::{de, section::*}; use crate::{resource::BlockTypes, types::*}; /// Chunk data structure wrapping a [de::Chunk] for convenient access to @@ -17,7 +14,7 @@ use crate::{resource::BlockTypes, types::*}; pub enum Chunk<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { - section_map: BTreeMap, BiomesV18<'a>)>, + section_map: BTreeMap, BiomesV18<'a>, BlockLight<'a>)>, }, /// Minecraft v1.13+ chunk /// @@ -26,14 +23,14 @@ pub enum Chunk<'a> { /// section), and a palette mapping these indices to namespaced /// block IDs V1_13 { - section_map: BTreeMap>, + section_map: BTreeMap, BlockLight<'a>)>, biomes: &'a de::BiomesV0, }, /// Original pre-1.13 chunk /// /// The original chunk format with fixed 8-bit numeric block IDs V0 { - section_map: BTreeMap>, + section_map: BTreeMap, BlockLight<'a>)>, biomes: &'a de::BiomesV0, }, /// Unpopulated chunk without any block data @@ -45,15 +42,15 @@ pub enum Chunk<'a> { enum SectionIterInner<'a> { /// Iterator over sections of [Chunk::V1_18] V1_18 { - iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV18<'a>)>, + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV18<'a>, BlockLight<'a>)>, }, /// Iterator over sections of [Chunk::V1_13] V1_13 { - iter: btree_map::Iter<'a, SectionY, SectionV1_13<'a>>, + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, }, /// Iterator over sections of [Chunk::V0] V0 { - iter: btree_map::Iter<'a, SectionY, SectionV0<'a>>, + iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, }, /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) Empty, @@ -101,6 +98,9 @@ impl<'a> Chunk<'a> { .with_context(|| { format!("Failed to load section biomes at Y={}", section.y) })?, + BlockLight::new(section.block_light.as_deref()).with_context(|| { + format!("Failed to load section block light at Y={}", section.y) + })?, ), ); } @@ -118,6 +118,10 @@ impl<'a> Chunk<'a> { let mut section_map_v0 = BTreeMap::new(); for section in &level.sections { + let block_light = + BlockLight::new(section.block_light.as_deref()).with_context(|| { + format!("Failed to load section block light at Y={}", section.y) + })?; match §ion.section { de::SectionV0Variants::V1_13 { block_states, @@ -125,16 +129,29 @@ impl<'a> Chunk<'a> { } => { 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))?, + ( + SectionV1_13::new( + data_version, + Some(block_states), + palette, + block_types, + ) + .with_context(|| { + format!("Failed to load section at Y={}", section.y) + })?, + block_light, + ), ); } de::SectionV0Variants::V0 { blocks, data } => { section_map_v0.insert( SectionY(section.y.into()), - SectionV0::new(blocks, data, block_types).with_context(|| { - format!("Failed to load section at Y={}", section.y) - })?, + ( + SectionV0::new(blocks, data, block_types).with_context(|| { + format!("Failed to load section at Y={}", section.y) + })?, + block_light, + ), ); } de::SectionV0Variants::Empty {} => {} @@ -207,15 +224,14 @@ impl<'a> SectionIter<'a> { F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T, { match &mut self.inner { - SectionIterInner::V1_18 { iter } => f(&mut iter.map(|(&y, section)| SectionIterItem { - y, - section: §ion.0, - })), + SectionIterInner::V1_18 { iter } => { + f(&mut iter.map(|(&y, (section, _, _))| SectionIterItem { y, section })) + } SectionIterInner::V1_13 { iter } => { - f(&mut iter.map(|(&y, section)| SectionIterItem { y, section })) + f(&mut iter.map(|(&y, (section, _))| SectionIterItem { y, section })) } SectionIterInner::V0 { iter } => { - f(&mut iter.map(|(&y, section)| SectionIterItem { y, section })) + f(&mut iter.map(|(&y, (section, _))| SectionIterItem { y, section })) } SectionIterInner::Empty => f(&mut iter::empty()), } From 51602d5fc1d79987f7a9c011c84db452ea175e64 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 17:32:58 +0100 Subject: [PATCH 138/460] world/chunk: add block light to section iterator items --- src/world/chunk.rs | 27 ++++++++++++++++++++++----- src/world/layer.rs | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 6895ea7..984d8fe 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -203,6 +203,7 @@ impl<'a> Chunk<'a> { pub struct SectionIterItem<'a> { pub y: SectionY, pub section: &'a dyn Section, + pub block_light: BlockLight<'a>, } trait SectionIterTrait<'a>: @@ -224,14 +225,30 @@ impl<'a> SectionIter<'a> { F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T, { match &mut self.inner { - SectionIterInner::V1_18 { iter } => { - f(&mut iter.map(|(&y, (section, _, _))| SectionIterItem { y, section })) - } + SectionIterInner::V1_18 { iter } => f(&mut iter.map( + |(&y, (section, _, block_light))| SectionIterItem { + y, + section, + block_light: *block_light, + }, + )), SectionIterInner::V1_13 { iter } => { - f(&mut iter.map(|(&y, (section, _))| SectionIterItem { y, section })) + f( + &mut iter.map(|(&y, (section, block_light))| SectionIterItem { + y, + section, + block_light: *block_light, + }), + ) } SectionIterInner::V0 { iter } => { - f(&mut iter.map(|(&y, (section, _))| SectionIterItem { y, section })) + f( + &mut iter.map(|(&y, (section, block_light))| SectionIterItem { + y, + section, + block_light: *block_light, + }), + ) } SectionIterInner::Empty => f(&mut iter::empty()), } diff --git a/src/world/layer.rs b/src/world/layer.rs index 5541e34..2fd879b 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -100,6 +100,7 @@ pub fn top_layer(chunk: &Chunk) -> Result> { for SectionIterItem { y: section_y, section, + block_light: _, } in chunk.sections().rev() { for y in BlockY::iter().rev() { From 202364bfca3b5ab84c07d1cdd76bb1e7d3cb6784 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 18:08:20 +0100 Subject: [PATCH 139/460] main: factor out overlay_chunk() function to build region images --- src/main.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 054b659..899e772 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,6 +59,19 @@ impl Config { } } +fn overlay_chunk(image: &mut I, chunk: &J, coords: ChunkCoords) +where + I: image::GenericImage, + J: image::GenericImageView, +{ + image::imageops::overlay( + image, + chunk, + coords.x.0 as i64 * BLOCKS_PER_CHUNK as i64, + coords.z.0 as i64 * BLOCKS_PER_CHUNK as i64, + ); +} + /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { block_types: resource::BlockTypes, @@ -209,12 +222,7 @@ impl<'a> TileRenderer<'a> { }, ) }); - image::imageops::overlay( - image, - &chunk_image, - coords.x.0 as i64 * BLOCKS_PER_CHUNK as i64, - coords.z.0 as i64 * BLOCKS_PER_CHUNK as i64, - ); + overlay_chunk(image, &chunk_image, coords); } fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { From 4fd316f3fceba0b5cdf97e349a88b937772573ea Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 20:33:10 +0100 Subject: [PATCH 140/460] world/layer: return None from top_layer() for empty chunks Allow ignoring these chunks for the light map as well. --- src/main.rs | 12 +++++++++--- src/world/chunk.rs | 9 +++++++++ src/world/layer.rs | 8 ++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 899e772..2ae6be3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -98,7 +98,10 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single chunk - fn process_chunk(&self, data: world::de::Chunk) -> Result> { + fn process_chunk( + &self, + data: world::de::Chunk, + ) -> Result>> { let chunk = world::chunk::Chunk::new(&data, &self.block_types)?; world::layer::top_layer(&chunk) } @@ -127,9 +130,12 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let processed_chunk = self + let Some(processed_chunk) = self .process_chunk(data) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))?; + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + else { + return Ok(()); + }; processed_region[chunk_coords] = Some(processed_chunk); Ok(()) }, diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 984d8fe..10efc6a 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -179,6 +179,15 @@ impl<'a> Chunk<'a> { ) } + 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, + } + } + /// Returns an interator over the chunk's sections and their Y coordinates pub fn sections(&self) -> SectionIter { use SectionIterInner::*; diff --git a/src/world/layer.rs b/src/world/layer.rs index 2fd879b..8f9897a 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -91,9 +91,13 @@ pub type BlockInfoArray = LayerBlockArray>; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk) -> Result> { +pub fn top_layer(chunk: &Chunk) -> Result>> { use BLOCKS_PER_CHUNK as N; + if chunk.is_empty() { + return Ok(None); + } + let mut done = 0; let mut ret = Box::::default(); @@ -129,5 +133,5 @@ pub fn top_layer(chunk: &Chunk) -> Result> { } } - Ok(ret) + Ok(Some(ret)) } From 116e7e5fb6c64dfb20e7ea08e8094e25dd5b8b4b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 17:38:52 +0100 Subject: [PATCH 141/460] world/layer: collect block light data with top layer --- src/world/layer.rs | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index 8f9897a..4036f4a 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -83,6 +83,7 @@ impl OptionBlockInfoExt for Option { } pub type BlockInfoArray = LayerBlockArray>; +pub type BlockLightArray = LayerBlockArray; /// Fills in a [BlockInfoArray] with the information of the chunk's top /// block layer @@ -91,7 +92,7 @@ pub type BlockInfoArray = LayerBlockArray>; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk) -> Result>> { +pub fn top_layer(chunk: &Chunk) -> Result, Box)>> { use BLOCKS_PER_CHUNK as N; if chunk.is_empty() { @@ -99,33 +100,42 @@ pub fn top_layer(chunk: &Chunk) -> Result>> { } let mut done = 0; - let mut ret = Box::::default(); + let mut blocks = Box::::default(); + let mut light = Box::::default(); for SectionIterItem { y: section_y, section, - block_light: _, + block_light, } in chunk.sections().rev() { for y in BlockY::iter().rev() { for xz in BlockInfoArray::keys() { - let entry = &mut ret[xz]; + let entry = &mut blocks[xz]; if entry.done() { continue; } let coords = SectionBlockCoords { xz, y }; - let Some(block_type) = section.block_at(coords)? else { - continue; + + 'check_block: { + let Some(block_type) = section.block_at(coords)? else { + break 'check_block; + }; + + let height = BlockHeight::new(section_y, y)?; + if !entry.fill(height, block_type) { + break 'check_block; + } + + assert!(entry.done()); + done += 1; }; - let height = BlockHeight::new(section_y, y)?; - if !entry.fill(height, block_type) { - continue; + + if entry.is_none() { + light[xz] = block_light.block_light_at(coords); } - assert!(entry.done()); - - done += 1; if done == N * N { break; } @@ -133,5 +143,5 @@ pub fn top_layer(chunk: &Chunk) -> Result>> { } } - Ok(Some(ret)) + Ok(Some((blocks, light))) } From fbf212b55f3b39e9138f297d1771c93c9b324d84 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 20:36:25 +0100 Subject: [PATCH 142/460] main: render light map --- src/main.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2ae6be3..3b72d4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,12 @@ use std::{ use anyhow::{Context, Result}; use clap::Parser; -use minedmap::{io::storage, resource, types::*, world}; +use minedmap::{ + io::storage, + resource, + types::*, + world::{self, layer::BlockLightArray}, +}; #[derive(Debug, Parser)] struct Args { @@ -22,6 +27,7 @@ type ProcessedRegion = ChunkArray>>; struct Config { region_dir: PathBuf, processed_dir: PathBuf, + light_dir: PathBuf, map_dir: PathBuf, } @@ -29,11 +35,13 @@ impl Config { fn new(args: Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + let light_dir = [&args.output_dir, Path::new("light/0")].iter().collect(); let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); Config { region_dir, processed_dir, + light_dir, map_dir, } } @@ -48,6 +56,16 @@ impl Config { [&self.processed_dir, Path::new(&filename)].iter().collect() } + fn light_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.png{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.light_dir, Path::new(&filename)].iter().collect() + } + fn map_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { let filename = format!( "r.{}.{}.png{}", @@ -101,11 +119,29 @@ impl<'a> RegionProcessor<'a> { fn process_chunk( &self, data: world::de::Chunk, - ) -> Result>> { + ) -> Result< + Option<( + Box, + Box, + )>, + > { let chunk = world::chunk::Chunk::new(&data, &self.block_types)?; world::layer::top_layer(&chunk) } + fn chunk_lightmap(block_light: Box) -> image::GrayAlphaImage { + const N: u32 = BLOCKS_PER_CHUNK as u32; + + image::GrayAlphaImage::from_fn(N, N, |x, z| { + let v: f32 = block_light[LayerBlockCoords { + x: BlockX(x as u8), + z: BlockZ(z as u8), + }] + .into(); + image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) + }) + } + fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { let tmp_path = self.config.processed_path(coords, true); storage::write(&tmp_path, processed_region)?; @@ -122,26 +158,52 @@ impl<'a> RegionProcessor<'a> { Ok(()) } + fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { + let tmp_path = self.config.light_path(coords, true); + lightmap + .save_with_format(&tmp_path, image::ImageFormat::Png) + .context("Failed to save image")?; + + let output_path = self.config.light_path(coords, false); + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; + + Ok(()) + } + /// Processes a single region file fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + println!("Processing region r.{}.{}.mca", coords.0, coords.1); let mut processed_region = ProcessedRegion::default(); + let mut lightmap = image::GrayAlphaImage::new(N, N); minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some(processed_chunk) = self + let Some((processed_chunk, block_light)) = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { return Ok(()); }; processed_region[chunk_coords] = Some(processed_chunk); + + let chunk_lightmap = Self::chunk_lightmap(block_light); + overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); + Ok(()) }, )?; self.save_region(coords, &processed_region)?; + self.save_lightmap(coords, &lightmap)?; Ok(()) } @@ -163,6 +225,12 @@ impl<'a> RegionProcessor<'a> { self.config.processed_dir.display(), ) })?; + fs::create_dir_all(&self.config.light_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.config.light_dir.display(), + ) + })?; let mut ret = Vec::new(); From 46802116d91a852b7f3edc1da7a09692337c30c3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 21:32:15 +0100 Subject: [PATCH 143/460] resource: change BlockColor into an array --- resource/generate.py | 2 +- src/main.rs | 4 +- src/resource/block_types.rs | 1876 +++++++++++++++++------------------ src/resource/mod.rs | 2 +- 4 files changed, 942 insertions(+), 942 deletions(-) diff --git a/resource/generate.py b/resource/generate.py index d91df98..4398ce4 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -36,7 +36,7 @@ with open(sys.argv[2], 'w') as f: flags.append('Water') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' - print('\t("%s", BlockType { flags: %s, color: BlockColor(%u, %u, %u) }),' % ( + print('\t("%s", BlockType { flags: %s, color: BlockColor([%u, %u, %u]) }),' % ( name, flags, info['color']['r'], diff --git a/src/main.rs b/src/main.rs index 3b72d4d..14589f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -289,8 +289,8 @@ impl<'a> TileRenderer<'a> { z: BlockZ(z as u8), }] { Some(block) => { - let c = block.block_type.color; - [c.0, c.1, c.2, 255] + let c = block.block_type.color.0; + [c[0], c[1], c[2], 255] } None => [0, 0, 0, 0], }, diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index 6afed2a..1520b8e 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -7,6566 +7,6566 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "acacia_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "acacia_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(167, 95, 60), + color: BlockColor([167, 95, 60]), }, ), ( "acacia_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor(149, 148, 148), + color: BlockColor([149, 148, 148]), }, ), ( "acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(150, 88, 55), + color: BlockColor([150, 88, 55]), }, ), ( "acacia_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(118, 117, 23), + color: BlockColor([118, 117, 23]), }, ), ( "acacia_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 90, 50), + color: BlockColor([168, 90, 50]), }, ), ( "acacia_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(156, 87, 51), + color: BlockColor([156, 87, 51]), }, ), ( "acacia_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 96, 86), + color: BlockColor([103, 96, 86]), }, ), ( "activator_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 87, 74), + color: BlockColor([115, 87, 74]), }, ), ( "air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "allium", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "amethyst_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(133, 97, 191), + color: BlockColor([133, 97, 191]), }, ), ( "amethyst_cluster", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(163, 126, 207), + color: BlockColor([163, 126, 207]), }, ), ( "ancient_debris", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(94, 66, 58), + color: BlockColor([94, 66, 58]), }, ), ( "andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 136, 136), + color: BlockColor([136, 136, 136]), }, ), ( "andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 136, 136), + color: BlockColor([136, 136, 136]), }, ), ( "andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 136, 136), + color: BlockColor([136, 136, 136]), }, ), ( "andesite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 136, 136), + color: BlockColor([136, 136, 136]), }, ), ( "anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 72), + color: BlockColor([72, 72, 72]), }, ), ( "attached_melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(141, 142, 141), + color: BlockColor([141, 142, 141]), }, ), ( "attached_pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(139, 139, 139), + color: BlockColor([139, 139, 139]), }, ), ( "azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 124, 47), + color: BlockColor([101, 124, 47]), }, ), ( "azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(90, 114, 44), + color: BlockColor([90, 114, 44]), }, ), ( "azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 144, 19), + color: BlockColor([93, 144, 19]), }, ), ( "bamboo_sapling", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "barrel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(134, 100, 58), + color: BlockColor([134, 100, 58]), }, ), ( "barrier", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 81, 86), + color: BlockColor([80, 81, 86]), }, ), ( "beacon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 220, 215), + color: BlockColor([117, 220, 215]), }, ), ( "bedrock", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(85, 85, 85), + color: BlockColor([85, 85, 85]), }, ), ( "bee_nest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(202, 160, 74), + color: BlockColor([202, 160, 74]), }, ), ( "beehive", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(180, 146, 90), + color: BlockColor([180, 146, 90]), }, ), ( "beetroots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 91, 30), + color: BlockColor([93, 91, 30]), }, ), ( "bell", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(253, 235, 110), + color: BlockColor([253, 235, 110]), }, ), ( "big_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(111, 141, 51), + color: BlockColor([111, 141, 51]), }, ), ( "big_dripleaf_stem", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "birch_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "birch_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(220, 209, 176), + color: BlockColor([220, 209, 176]), }, ), ( "birch_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Birch}), - color: BlockColor(130, 129, 130), + color: BlockColor([130, 129, 130]), }, ), ( "birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(193, 179, 135), + color: BlockColor([193, 179, 135]), }, ), ( "birch_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 160, 79), + color: BlockColor([127, 160, 79]), }, ), ( "birch_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 175, 121), + color: BlockColor([192, 175, 121]), }, ), ( "birch_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(207, 194, 157), + color: BlockColor([207, 194, 157]), }, ), ( "birch_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(216, 215, 210), + color: BlockColor([216, 215, 210]), }, ), ( "black_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "black_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "black_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "black_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "black_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 21, 25), + color: BlockColor([20, 21, 25]), }, ), ( "black_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(8, 10, 15), + color: BlockColor([8, 10, 15]), }, ), ( "black_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(25, 26, 31), + color: BlockColor([25, 26, 31]), }, ), ( "black_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(67, 30, 32), + color: BlockColor([67, 30, 32]), }, ), ( "black_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(25, 25, 29), + color: BlockColor([25, 25, 29]), }, ), ( "black_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(25, 25, 25), + color: BlockColor([25, 25, 25]), }, ), ( "black_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(24, 24, 24), + color: BlockColor([24, 24, 24]), }, ), ( "black_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(37, 22, 16), + color: BlockColor([37, 22, 16]), }, ), ( "black_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "black_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 21, 25), + color: BlockColor([20, 21, 25]), }, ), ( "blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(42, 36, 41), + color: BlockColor([42, 36, 41]), }, ), ( "blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(42, 36, 41), + color: BlockColor([42, 36, 41]), }, ), ( "blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(42, 36, 41), + color: BlockColor([42, 36, 41]), }, ), ( "blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(42, 36, 41), + color: BlockColor([42, 36, 41]), }, ), ( "blast_furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 80, 81), + color: BlockColor([80, 80, 81]), }, ), ( "blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 57, 157), + color: BlockColor([53, 57, 157]), }, ), ( "blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 46, 143), + color: BlockColor([44, 46, 143]), }, ), ( "blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 73, 166), + color: BlockColor([70, 73, 166]), }, ), ( "blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 64, 139), + color: BlockColor([47, 64, 139]), }, ), ( "blue_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(116, 167, 253), + color: BlockColor([116, 167, 253]), }, ), ( "blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 45, 140), + color: BlockColor([43, 45, 140]), }, ), ( "blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(51, 76, 178), + color: BlockColor([51, 76, 178]), }, ), ( "blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(48, 73, 171), + color: BlockColor([48, 73, 171]), }, ), ( "blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(74, 59, 91), + color: BlockColor([74, 59, 91]), }, ), ( "blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 57, 157), + color: BlockColor([53, 57, 157]), }, ), ( "bone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(209, 206, 179), + color: BlockColor([209, 206, 179]), }, ), ( "bookshelf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(207, 91, 159), + color: BlockColor([207, 91, 159]), }, ), ( "brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brewing_stand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 100, 80), + color: BlockColor([122, 100, 80]), }, ), ( "brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(150, 97, 83), + color: BlockColor([150, 97, 83]), }, ), ( "brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(150, 97, 83), + color: BlockColor([150, 97, 83]), }, ), ( "brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(150, 97, 83), + color: BlockColor([150, 97, 83]), }, ), ( "bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(150, 97, 83), + color: BlockColor([150, 97, 83]), }, ), ( "brown_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brown_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brown_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brown_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "brown_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 71, 40), + color: BlockColor([114, 71, 40]), }, ), ( "brown_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(96, 59, 31), + color: BlockColor([96, 59, 31]), }, ), ( "brown_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 84, 53), + color: BlockColor([125, 84, 53]), }, ), ( "brown_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 106, 85), + color: BlockColor([119, 106, 85]), }, ), ( "brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brown_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 111, 81), + color: BlockColor([149, 111, 81]), }, ), ( "brown_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(106, 66, 35), + color: BlockColor([106, 66, 35]), }, ), ( "brown_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(102, 76, 51), + color: BlockColor([102, 76, 51]), }, ), ( "brown_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(97, 73, 48), + color: BlockColor([97, 73, 48]), }, ), ( "brown_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 51, 35), + color: BlockColor([77, 51, 35]), }, ), ( "brown_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "brown_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 71, 40), + color: BlockColor([114, 71, 40]), }, ), ( "bubble_column", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: BlockColor(177, 177, 177), + color: BlockColor([177, 177, 177]), }, ), ( "bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(165, 26, 162), + color: BlockColor([165, 26, 162]), }, ), ( "bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "budding_amethyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(132, 96, 186), + color: BlockColor([132, 96, 186]), }, ), ( "cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(85, 127, 43), + color: BlockColor([85, 127, 43]), }, ), ( "cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "calcite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 224, 220), + color: BlockColor([223, 224, 220]), }, ), ( "campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 88, 54), + color: BlockColor([110, 88, 54]), }, ), ( "candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "carrots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(81, 124, 37), + color: BlockColor([81, 124, 37]), }, ), ( "cartography_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 87, 67), + color: BlockColor([103, 87, 67]), }, ), ( "carved_pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(198, 118, 24), + color: BlockColor([198, 118, 24]), }, ), ( "cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 72, 74), + color: BlockColor([73, 72, 74]), }, ), ( "cave_air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cave_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(90, 109, 40), + color: BlockColor([90, 109, 40]), }, ), ( "cave_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(88, 101, 38), + color: BlockColor([88, 101, 38]), }, ), ( "chain", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "chain_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 161, 147), + color: BlockColor([131, 161, 147]), }, ), ( "chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "chipped_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 72), + color: BlockColor([72, 72, 72]), }, ), ( "chiseled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 54, 54), + color: BlockColor([54, 54, 54]), }, ), ( "chiseled_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 23, 28), + color: BlockColor([47, 23, 28]), }, ), ( "chiseled_polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "chiseled_quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(231, 226, 218), + color: BlockColor([231, 226, 218]), }, ), ( "chiseled_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "chiseled_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 118, 119), + color: BlockColor([119, 118, 119]), }, ), ( "chorus_flower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(151, 120, 151), + color: BlockColor([151, 120, 151]), }, ), ( "chorus_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 57, 93), + color: BlockColor([93, 57, 93]), }, ), ( "clay", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 166, 179), + color: BlockColor([160, 166, 179]), }, ), ( "coal_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(16, 15, 15), + color: BlockColor([16, 15, 15]), }, ), ( "coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(105, 105, 105), + color: BlockColor([105, 105, 105]), }, ), ( "coarse_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 85, 59), + color: BlockColor([119, 85, 59]), }, ), ( "cobbled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 77, 80), + color: BlockColor([77, 77, 80]), }, ), ( "cobbled_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 77, 80), + color: BlockColor([77, 77, 80]), }, ), ( "cobbled_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 77, 80), + color: BlockColor([77, 77, 80]), }, ), ( "cobbled_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 77, 80), + color: BlockColor([77, 77, 80]), }, ), ( "cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 127, 127), + color: BlockColor([127, 127, 127]), }, ), ( "cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 127, 127), + color: BlockColor([127, 127, 127]), }, ), ( "cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 127, 127), + color: BlockColor([127, 127, 127]), }, ), ( "cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 127, 127), + color: BlockColor([127, 127, 127]), }, ), ( "cobweb", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(228, 233, 234), + color: BlockColor([228, 233, 234]), }, ), ( "cocoa", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 91, 40), + color: BlockColor([154, 91, 40]), }, ), ( "command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 136, 108), + color: BlockColor([181, 136, 108]), }, ), ( "comparator", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(166, 161, 159), + color: BlockColor([166, 161, 159]), }, ), ( "composter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(88, 61, 23), + color: BlockColor([88, 61, 23]), }, ), ( "conduit", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(159, 139, 113), + color: BlockColor([159, 139, 113]), }, ), ( "copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 107, 79), + color: BlockColor([192, 107, 79]), }, ), ( "copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(124, 125, 120), + color: BlockColor([124, 125, 120]), }, ), ( "cornflower", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cracked_deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(64, 64, 65), + color: BlockColor([64, 64, 65]), }, ), ( "cracked_deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(52, 52, 52), + color: BlockColor([52, 52, 52]), }, ), ( "cracked_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(40, 20, 23), + color: BlockColor([40, 20, 23]), }, ), ( "cracked_polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 37, 43), + color: BlockColor([44, 37, 43]), }, ), ( "cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(118, 117, 118), + color: BlockColor([118, 117, 118]), }, ), ( "crafting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 73, 42), + color: BlockColor([119, 73, 42]), }, ), ( "creeper_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "creeper_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "crimson_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "crimson_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 54, 79), + color: BlockColor([114, 54, 79]), }, ), ( "crimson_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(92, 25, 29), + color: BlockColor([92, 25, 29]), }, ), ( "crimson_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(130, 31, 31), + color: BlockColor([130, 31, 31]), }, ), ( "crimson_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(126, 8, 41), + color: BlockColor([126, 8, 41]), }, ), ( "crimson_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 48, 70), + color: BlockColor([101, 48, 70]), }, ), ( "crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 49, 70), + color: BlockColor([112, 49, 70]), }, ), ( "crimson_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 50, 72), + color: BlockColor([103, 50, 72]), }, ), ( "crimson_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "crying_obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(32, 10, 60), + color: BlockColor([32, 10, 60]), }, ), ( "cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "cut_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "cut_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "cut_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "cut_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "cyan_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cyan_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cyan_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cyan_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "cyan_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(21, 137, 145), + color: BlockColor([21, 137, 145]), }, ), ( "cyan_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(21, 119, 136), + color: BlockColor([21, 119, 136]), }, ), ( "cyan_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(36, 147, 157), + color: BlockColor([36, 147, 157]), }, ), ( "cyan_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(52, 118, 125), + color: BlockColor([52, 118, 125]), }, ), ( "cyan_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 121, 135), + color: BlockColor([20, 121, 135]), }, ), ( "cyan_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(76, 127, 153), + color: BlockColor([76, 127, 153]), }, ), ( "cyan_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 122, 147), + color: BlockColor([73, 122, 147]), }, ), ( "cyan_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(86, 91, 91), + color: BlockColor([86, 91, 91]), }, ), ( "cyan_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "cyan_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(21, 137, 145), + color: BlockColor([21, 137, 145]), }, ), ( "damaged_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 72), + color: BlockColor([72, 72, 72]), }, ), ( "dandelion", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dark_oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dark_oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(76, 51, 25), + color: BlockColor([76, 51, 25]), }, ), ( "dark_oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor(150, 150, 150), + color: BlockColor([150, 150, 150]), }, ), ( "dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(67, 45, 22), + color: BlockColor([67, 45, 22]), }, ), ( "dark_oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(61, 90, 30), + color: BlockColor([61, 90, 30]), }, ), ( "dark_oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 43, 20), + color: BlockColor([66, 43, 20]), }, ), ( "dark_oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(75, 49, 23), + color: BlockColor([75, 49, 23]), }, ), ( "dark_oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(60, 46, 26), + color: BlockColor([60, 46, 26]), }, ), ( "dark_prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(51, 91, 75), + color: BlockColor([51, 91, 75]), }, ), ( "dark_prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(51, 91, 75), + color: BlockColor([51, 91, 75]), }, ), ( "dark_prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(51, 91, 75), + color: BlockColor([51, 91, 75]), }, ), ( "daylight_detector", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(130, 116, 94), + color: BlockColor([130, 116, 94]), }, ), ( "dead_brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(124, 117, 114), + color: BlockColor([124, 117, 114]), }, ), ( "dead_brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 123, 119), + color: BlockColor([131, 123, 119]), }, ), ( "dead_bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(107, 78, 40), + color: BlockColor([107, 78, 40]), }, ), ( "dead_fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 123, 119), + color: BlockColor([131, 123, 119]), }, ), ( "dead_fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(133, 126, 122), + color: BlockColor([133, 126, 122]), }, ), ( "dead_horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(130, 123, 119), + color: BlockColor([130, 123, 119]), }, ), ( "dead_tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dead_tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 80, 82), + color: BlockColor([80, 80, 82]), }, ), ( "deepslate_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 70, 71), + color: BlockColor([70, 70, 71]), }, ), ( "deepslate_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 70, 71), + color: BlockColor([70, 70, 71]), }, ), ( "deepslate_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 70, 71), + color: BlockColor([70, 70, 71]), }, ), ( "deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 70, 71), + color: BlockColor([70, 70, 71]), }, ), ( "deepslate_coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(74, 74, 76), + color: BlockColor([74, 74, 76]), }, ), ( "deepslate_copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(92, 93, 89), + color: BlockColor([92, 93, 89]), }, ), ( "deepslate_diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(83, 106, 106), + color: BlockColor([83, 106, 106]), }, ), ( "deepslate_emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(78, 104, 87), + color: BlockColor([78, 104, 87]), }, ), ( "deepslate_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 102, 78), + color: BlockColor([115, 102, 78]), }, ), ( "deepslate_iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(106, 99, 94), + color: BlockColor([106, 99, 94]), }, ), ( "deepslate_lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 90, 115), + color: BlockColor([79, 90, 115]), }, ), ( "deepslate_redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(104, 73, 74), + color: BlockColor([104, 73, 74]), }, ), ( "deepslate_tile_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 54, 55), + color: BlockColor([54, 54, 55]), }, ), ( "deepslate_tile_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 54, 55), + color: BlockColor([54, 54, 55]), }, ), ( "deepslate_tile_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 54, 55), + color: BlockColor([54, 54, 55]), }, ), ( "deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 54, 55), + color: BlockColor([54, 54, 55]), }, ), ( "detector_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(123, 104, 90), + color: BlockColor([123, 104, 90]), }, ), ( "diamond_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(98, 237, 228), + color: BlockColor([98, 237, 228]), }, ), ( "diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(121, 141, 140), + color: BlockColor([121, 141, 140]), }, ), ( "diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(188, 188, 188), + color: BlockColor([188, 188, 188]), }, ), ( "diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(188, 188, 188), + color: BlockColor([188, 188, 188]), }, ), ( "diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(188, 188, 188), + color: BlockColor([188, 188, 188]), }, ), ( "diorite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(188, 188, 188), + color: BlockColor([188, 188, 188]), }, ), ( "dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(134, 96, 67), + color: BlockColor([134, 96, 67]), }, ), ( "dirt_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(148, 121, 65), + color: BlockColor([148, 121, 65]), }, ), ( "dispenser", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 109, 109), + color: BlockColor([110, 109, 109]), }, ), ( "dragon_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(12, 9, 15), + color: BlockColor([12, 9, 15]), }, ), ( "dragon_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dragon_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "dried_kelp_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(50, 58, 38), + color: BlockColor([50, 58, 38]), }, ), ( "dripstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(134, 107, 92), + color: BlockColor([134, 107, 92]), }, ), ( "dropper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 109, 109), + color: BlockColor([110, 109, 109]), }, ), ( "emerald_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(42, 203, 87), + color: BlockColor([42, 203, 87]), }, ), ( "emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(108, 136, 115), + color: BlockColor([108, 136, 115]), }, ), ( "enchanting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(128, 75, 85), + color: BlockColor([128, 75, 85]), }, ), ( "end_gateway", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(15, 10, 24), + color: BlockColor([15, 10, 24]), }, ), ( "end_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(15, 10, 24), + color: BlockColor([15, 10, 24]), }, ), ( "end_portal_frame", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(91, 120, 97), + color: BlockColor([91, 120, 97]), }, ), ( "end_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "end_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(219, 222, 158), + color: BlockColor([219, 222, 158]), }, ), ( "end_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(218, 224, 162), + color: BlockColor([218, 224, 162]), }, ), ( "end_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(218, 224, 162), + color: BlockColor([218, 224, 162]), }, ), ( "end_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(218, 224, 162), + color: BlockColor([218, 224, 162]), }, ), ( "end_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(218, 224, 162), + color: BlockColor([218, 224, 162]), }, ), ( "ender_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(15, 10, 24), + color: BlockColor([15, 10, 24]), }, ), ( "exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(161, 125, 103), + color: BlockColor([161, 125, 103]), }, ), ( "exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "farmland", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(81, 44, 15), + color: BlockColor([81, 44, 15]), }, ), ( "fern", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(211, 140, 53), + color: BlockColor([211, 140, 53]), }, ), ( "fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(163, 35, 46), + color: BlockColor([163, 35, 46]), }, ), ( "fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "fletching_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(197, 180, 133), + color: BlockColor([197, 180, 133]), }, ), ( "flower_pot", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(124, 68, 53), + color: BlockColor([124, 68, 53]), }, ), ( "flowering_azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 121, 64), + color: BlockColor([112, 121, 64]), }, ), ( "flowering_azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 111, 60), + color: BlockColor([99, 111, 60]), }, ), ( "frogspawn", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(105, 90, 82), + color: BlockColor([105, 90, 82]), }, ), ( "frosted_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(140, 181, 252), + color: BlockColor([140, 181, 252]), }, ), ( "furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 109, 109), + color: BlockColor([110, 109, 109]), }, ), ( "gilded_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(55, 42, 38), + color: BlockColor([55, 42, 38]), }, ), ( "glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(175, 213, 219), + color: BlockColor([175, 213, 219]), }, ), ( "glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(170, 210, 217), + color: BlockColor([170, 210, 217]), }, ), ( "glow_item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "glow_lichen", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "glowstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(171, 131, 84), + color: BlockColor([171, 131, 84]), }, ), ( "gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(246, 208, 61), + color: BlockColor([246, 208, 61]), }, ), ( "gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(145, 133, 106), + color: BlockColor([145, 133, 106]), }, ), ( "granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 103, 85), + color: BlockColor([149, 103, 85]), }, ), ( "granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 103, 85), + color: BlockColor([149, 103, 85]), }, ), ( "granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 103, 85), + color: BlockColor([149, 103, 85]), }, ), ( "granite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 103, 85), + color: BlockColor([149, 103, 85]), }, ), ( "grass", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "grass_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(147, 147, 147), + color: BlockColor([147, 147, 147]), }, ), ( "grass_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(148, 121, 65), + color: BlockColor([148, 121, 65]), }, ), ( "gravel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 127, 126), + color: BlockColor([131, 127, 126]), }, ), ( "gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(62, 68, 71), + color: BlockColor([62, 68, 71]), }, ), ( "gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(54, 57, 61), + color: BlockColor([54, 57, 61]), }, ), ( "gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(76, 81, 84), + color: BlockColor([76, 81, 84]), }, ), ( "gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(83, 90, 93), + color: BlockColor([83, 90, 93]), }, ), ( "gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(55, 58, 62), + color: BlockColor([55, 58, 62]), }, ), ( "gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(76, 76, 76), + color: BlockColor([76, 76, 76]), }, ), ( "gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 73, 73), + color: BlockColor([73, 73, 73]), }, ), ( "gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(57, 42, 35), + color: BlockColor([57, 42, 35]), }, ), ( "gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(62, 68, 71), + color: BlockColor([62, 68, 71]), }, ), ( "green_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "green_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "green_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "green_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "green_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(84, 109, 27), + color: BlockColor([84, 109, 27]), }, ), ( "green_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 91, 36), + color: BlockColor([73, 91, 36]), }, ), ( "green_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(97, 119, 44), + color: BlockColor([97, 119, 44]), }, ), ( "green_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 142, 67), + color: BlockColor([117, 142, 67]), }, ), ( "green_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 100, 31), + color: BlockColor([79, 100, 31]), }, ), ( "green_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(102, 127, 51), + color: BlockColor([102, 127, 51]), }, ), ( "green_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(97, 122, 48), + color: BlockColor([97, 122, 48]), }, ), ( "green_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(76, 83, 42), + color: BlockColor([76, 83, 42]), }, ), ( "green_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "green_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(84, 109, 27), + color: BlockColor([84, 109, 27]), }, ), ( "grindstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 142, 142), + color: BlockColor([142, 142, 142]), }, ), ( "hanging_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(161, 115, 91), + color: BlockColor([161, 115, 91]), }, ), ( "hay_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(165, 139, 12), + color: BlockColor([165, 139, 12]), }, ), ( "heavy_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(220, 220, 220), + color: BlockColor([220, 220, 220]), }, ), ( "honey_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(251, 185, 52), + color: BlockColor([251, 185, 52]), }, ), ( "honeycomb_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(229, 148, 29), + color: BlockColor([229, 148, 29]), }, ), ( "hopper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(75, 74, 75), + color: BlockColor([75, 74, 75]), }, ), ( "horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(216, 199, 66), + color: BlockColor([216, 199, 66]), }, ), ( "horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(145, 183, 253), + color: BlockColor([145, 183, 253]), }, ), ( "infested_chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 118, 119), + color: BlockColor([119, 118, 119]), }, ), ( "infested_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 127, 127), + color: BlockColor([127, 127, 127]), }, ), ( "infested_cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(118, 117, 118), + color: BlockColor([118, 117, 118]), }, ), ( "infested_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 80, 82), + color: BlockColor([80, 80, 82]), }, ), ( "infested_mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 121, 105), + color: BlockColor([115, 121, 105]), }, ), ( "infested_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "infested_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 121, 122), + color: BlockColor([122, 121, 122]), }, ), ( "iron_bars", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 139, 135), + color: BlockColor([136, 139, 135]), }, ), ( "iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(220, 220, 220), + color: BlockColor([220, 220, 220]), }, ), ( "iron_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(194, 193, 193), + color: BlockColor([194, 193, 193]), }, ), ( "iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(136, 129, 122), + color: BlockColor([136, 129, 122]), }, ), ( "iron_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(202, 202, 202), + color: BlockColor([202, 202, 202]), }, ), ( "item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "jack_o_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(214, 152, 52), + color: BlockColor([214, 152, 52]), }, ), ( "jigsaw", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 69, 81), + color: BlockColor([80, 69, 81]), }, ), ( "jukebox", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 64, 47), + color: BlockColor([93, 64, 47]), }, ), ( "jungle_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "jungle_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(163, 119, 84), + color: BlockColor([163, 119, 84]), }, ), ( "jungle_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor(156, 154, 143), + color: BlockColor([156, 154, 143]), }, ), ( "jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 109, 70), + color: BlockColor([149, 109, 70]), }, ), ( "jungle_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 81, 16), + color: BlockColor([47, 81, 16]), }, ), ( "jungle_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 115, 80), + color: BlockColor([160, 115, 80]), }, ), ( "jungle_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(152, 110, 77), + color: BlockColor([152, 110, 77]), }, ), ( "jungle_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(85, 67, 25), + color: BlockColor([85, 67, 25]), }, ), ( "kelp", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "kelp_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(86, 130, 42), + color: BlockColor([86, 130, 42]), }, ), ( "ladder", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(106, 91, 83), + color: BlockColor([106, 91, 83]), }, ), ( "lapis_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(30, 67, 140), + color: BlockColor([30, 67, 140]), }, ), ( "lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(107, 117, 141), + color: BlockColor([107, 117, 141]), }, ), ( "large_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "large_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "lava", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(212, 90, 18), + color: BlockColor([212, 90, 18]), }, ), ( "lava_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 72, 74), + color: BlockColor([73, 72, 74]), }, ), ( "lectern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(173, 137, 83), + color: BlockColor([173, 137, 83]), }, ), ( "lever", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "light_blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(58, 175, 217), + color: BlockColor([58, 175, 217]), }, ), ( "light_blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(35, 137, 198), + color: BlockColor([35, 137, 198]), }, ), ( "light_blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(74, 180, 213), + color: BlockColor([74, 180, 213]), }, ), ( "light_blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(94, 164, 208), + color: BlockColor([94, 164, 208]), }, ), ( "light_blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(49, 163, 212), + color: BlockColor([49, 163, 212]), }, ), ( "light_blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(102, 153, 216), + color: BlockColor([102, 153, 216]), }, ), ( "light_blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(97, 147, 208), + color: BlockColor([97, 147, 208]), }, ), ( "light_blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(113, 108, 137), + color: BlockColor([113, 108, 137]), }, ), ( "light_blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(58, 175, 217), + color: BlockColor([58, 175, 217]), }, ), ( "light_gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "light_gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 142, 134), + color: BlockColor([142, 142, 134]), }, ), ( "light_gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 115), + color: BlockColor([125, 125, 115]), }, ), ( "light_gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 154, 148), + color: BlockColor([154, 154, 148]), }, ), ( "light_gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(144, 166, 167), + color: BlockColor([144, 166, 167]), }, ), ( "light_gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(124, 124, 115), + color: BlockColor([124, 124, 115]), }, ), ( "light_gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(153, 153, 153), + color: BlockColor([153, 153, 153]), }, ), ( "light_gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(147, 147, 147), + color: BlockColor([147, 147, 147]), }, ), ( "light_gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(135, 106, 97), + color: BlockColor([135, 106, 97]), }, ), ( "light_gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "light_gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 142, 134), + color: BlockColor([142, 142, 134]), }, ), ( "light_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(246, 208, 61), + color: BlockColor([246, 208, 61]), }, ), ( "lightning_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lilac", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 125, 147), + color: BlockColor([154, 125, 147]), }, ), ( "lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lily_pad", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(133, 133, 133), + color: BlockColor([133, 133, 133]), }, ), ( "lime_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lime_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lime_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lime_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "lime_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 185, 25), + color: BlockColor([112, 185, 25]), }, ), ( "lime_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(94, 168, 24), + color: BlockColor([94, 168, 24]), }, ), ( "lime_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 189, 41), + color: BlockColor([125, 189, 41]), }, ), ( "lime_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 197, 55), + color: BlockColor([162, 197, 55]), }, ), ( "lime_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 172, 23), + color: BlockColor([99, 172, 23]), }, ), ( "lime_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 204, 25), + color: BlockColor([127, 204, 25]), }, ), ( "lime_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 196, 24), + color: BlockColor([122, 196, 24]), }, ), ( "lime_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 117, 52), + color: BlockColor([103, 117, 52]), }, ), ( "lime_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "lime_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 185, 25), + color: BlockColor([112, 185, 25]), }, ), ( "lodestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(147, 149, 152), + color: BlockColor([147, 149, 152]), }, ), ( "loom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 119, 91), + color: BlockColor([142, 119, 91]), }, ), ( "magenta_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "magenta_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "magenta_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "magenta_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "magenta_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(189, 68, 179), + color: BlockColor([189, 68, 179]), }, ), ( "magenta_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(169, 48, 159), + color: BlockColor([169, 48, 159]), }, ), ( "magenta_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 83, 184), + color: BlockColor([192, 83, 184]), }, ), ( "magenta_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(208, 100, 191), + color: BlockColor([208, 100, 191]), }, ), ( "magenta_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(173, 54, 163), + color: BlockColor([173, 54, 163]), }, ), ( "magenta_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(178, 76, 216), + color: BlockColor([178, 76, 216]), }, ), ( "magenta_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(171, 73, 208), + color: BlockColor([171, 73, 208]), }, ), ( "magenta_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(149, 88, 108), + color: BlockColor([149, 88, 108]), }, ), ( "magenta_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "magenta_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(189, 68, 179), + color: BlockColor([189, 68, 179]), }, ), ( "magma_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 63, 31), + color: BlockColor([142, 63, 31]), }, ), ( "mangrove_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "mangrove_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 48, 46), + color: BlockColor([112, 48, 46]), }, ), ( "mangrove_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor(129, 128, 128), + color: BlockColor([129, 128, 128]), }, ), ( "mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(102, 48, 42), + color: BlockColor([102, 48, 42]), }, ), ( "mangrove_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(96, 174, 83), + color: BlockColor([96, 174, 83]), }, ), ( "mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(74, 59, 38), + color: BlockColor([74, 59, 38]), }, ), ( "mangrove_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 54, 48), + color: BlockColor([117, 54, 48]), }, ), ( "mangrove_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 46, 42), + color: BlockColor([110, 46, 42]), }, ), ( "mangrove_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(83, 66, 41), + color: BlockColor([83, 66, 41]), }, ), ( "medium_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "melon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(111, 144, 30), + color: BlockColor([111, 144, 30]), }, ), ( "melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(153, 153, 153), + color: BlockColor([153, 153, 153]), }, ), ( "moss_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(89, 109, 45), + color: BlockColor([89, 109, 45]), }, ), ( "moss_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(89, 109, 45), + color: BlockColor([89, 109, 45]), }, ), ( "mossy_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 118, 94), + color: BlockColor([110, 118, 94]), }, ), ( "mossy_cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 118, 94), + color: BlockColor([110, 118, 94]), }, ), ( "mossy_cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 118, 94), + color: BlockColor([110, 118, 94]), }, ), ( "mossy_cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(110, 118, 94), + color: BlockColor([110, 118, 94]), }, ), ( "mossy_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 121, 105), + color: BlockColor([115, 121, 105]), }, ), ( "mossy_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 121, 105), + color: BlockColor([115, 121, 105]), }, ), ( "mossy_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 121, 105), + color: BlockColor([115, 121, 105]), }, ), ( "mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 121, 105), + color: BlockColor([115, 121, 105]), }, ), ( "moving_piston", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(60, 57, 60), + color: BlockColor([60, 57, 60]), }, ), ( "mud_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 103, 79), + color: BlockColor([137, 103, 79]), }, ), ( "mud_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 103, 79), + color: BlockColor([137, 103, 79]), }, ), ( "mud_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 103, 79), + color: BlockColor([137, 103, 79]), }, ), ( "mud_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 103, 79), + color: BlockColor([137, 103, 79]), }, ), ( "muddy_mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(70, 58, 45), + color: BlockColor([70, 58, 45]), }, ), ( "mushroom_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(203, 196, 185), + color: BlockColor([203, 196, 185]), }, ), ( "mycelium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(111, 98, 101), + color: BlockColor([111, 98, 101]), }, ), ( "nether_brick_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 21, 26), + color: BlockColor([44, 21, 26]), }, ), ( "nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 21, 26), + color: BlockColor([44, 21, 26]), }, ), ( "nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 21, 26), + color: BlockColor([44, 21, 26]), }, ), ( "nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 21, 26), + color: BlockColor([44, 21, 26]), }, ), ( "nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 21, 26), + color: BlockColor([44, 21, 26]), }, ), ( "nether_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 54, 42), + color: BlockColor([115, 54, 42]), }, ), ( "nether_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(89, 11, 192), + color: BlockColor([89, 11, 192]), }, ), ( "nether_quartz_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(117, 65, 62), + color: BlockColor([117, 65, 62]), }, ), ( "nether_sprouts", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(19, 151, 133), + color: BlockColor([19, 151, 133]), }, ), ( "nether_wart", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(111, 18, 19), + color: BlockColor([111, 18, 19]), }, ), ( "nether_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 2, 2), + color: BlockColor([114, 2, 2]), }, ), ( "netherite_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(66, 61, 63), + color: BlockColor([66, 61, 63]), }, ), ( "netherrack", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(97, 38, 38), + color: BlockColor([97, 38, 38]), }, ), ( "note_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(88, 58, 40), + color: BlockColor([88, 58, 40]), }, ), ( "oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(140, 110, 66), + color: BlockColor([140, 110, 66]), }, ), ( "oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor(144, 144, 144), + color: BlockColor([144, 144, 144]), }, ), ( "oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(151, 121, 73), + color: BlockColor([151, 121, 73]), }, ), ( "oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 106, 40), + color: BlockColor([77, 106, 40]), }, ), ( "oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(124, 99, 56), + color: BlockColor([124, 99, 56]), }, ), ( "oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 85, 50), + color: BlockColor([109, 85, 50]), }, ), ( "observer", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(98, 98, 98), + color: BlockColor([98, 98, 98]), }, ), ( "obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(15, 10, 24), + color: BlockColor([15, 10, 24]), }, ), ( "ochre_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(250, 245, 206), + color: BlockColor([250, 245, 206]), }, ), ( "orange_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "orange_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "orange_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "orange_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "orange_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(240, 118, 19), + color: BlockColor([240, 118, 19]), }, ), ( "orange_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(224, 97, 0), + color: BlockColor([224, 97, 0]), }, ), ( "orange_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(227, 131, 31), + color: BlockColor([227, 131, 31]), }, ), ( "orange_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 147, 91), + color: BlockColor([154, 147, 91]), }, ), ( "orange_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(234, 106, 8), + color: BlockColor([234, 106, 8]), }, ), ( "orange_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(216, 127, 51), + color: BlockColor([216, 127, 51]), }, ), ( "orange_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(208, 122, 48), + color: BlockColor([208, 122, 48]), }, ), ( "orange_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(161, 83, 37), + color: BlockColor([161, 83, 37]), }, ), ( "orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "orange_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "orange_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(240, 118, 19), + color: BlockColor([240, 118, 19]), }, ), ( "oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(82, 162, 132), + color: BlockColor([82, 162, 132]), }, ), ( "oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "packed_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(141, 180, 250), + color: BlockColor([141, 180, 250]), }, ), ( "packed_mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 106, 79), + color: BlockColor([142, 106, 79]), }, ), ( "pearlescent_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(245, 240, 239), + color: BlockColor([245, 240, 239]), }, ), ( "peony", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(129, 126, 139), + color: BlockColor([129, 126, 139]), }, ), ( "petrified_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "pink_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "pink_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "pink_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "pink_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "pink_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(237, 141, 172), + color: BlockColor([237, 141, 172]), }, ), ( "pink_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(213, 101, 142), + color: BlockColor([213, 101, 142]), }, ), ( "pink_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(228, 153, 181), + color: BlockColor([228, 153, 181]), }, ), ( "pink_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 154, 181), + color: BlockColor([235, 154, 181]), }, ), ( "pink_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(230, 121, 157), + color: BlockColor([230, 121, 157]), }, ), ( "pink_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(242, 127, 165), + color: BlockColor([242, 127, 165]), }, ), ( "pink_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(233, 122, 159), + color: BlockColor([233, 122, 159]), }, ), ( "pink_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(161, 78, 78), + color: BlockColor([161, 78, 78]), }, ), ( "pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "pink_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "pink_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(237, 141, 172), + color: BlockColor([237, 141, 172]), }, ), ( "piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 104, 96), + color: BlockColor([109, 104, 96]), }, ), ( "piston_head", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(153, 127, 85), + color: BlockColor([153, 127, 85]), }, ), ( "player_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "player_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "podzol", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(91, 63, 24), + color: BlockColor([91, 63, 24]), }, ), ( "pointed_dripstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(129, 102, 89), + color: BlockColor([129, 102, 89]), }, ), ( "polished_andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(132, 134, 133), + color: BlockColor([132, 134, 133]), }, ), ( "polished_andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(132, 134, 133), + color: BlockColor([132, 134, 133]), }, ), ( "polished_andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(132, 134, 133), + color: BlockColor([132, 134, 133]), }, ), ( "polished_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 98, 100), + color: BlockColor([99, 98, 100]), }, ), ( "polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "polished_blackstone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(48, 42, 49), + color: BlockColor([48, 42, 49]), }, ), ( "polished_blackstone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(48, 42, 49), + color: BlockColor([48, 42, 49]), }, ), ( "polished_blackstone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(48, 42, 49), + color: BlockColor([48, 42, 49]), }, ), ( "polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(48, 42, 49), + color: BlockColor([48, 42, 49]), }, ), ( "polished_blackstone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "polished_blackstone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "polished_blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "polished_blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "polished_blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 48, 56), + color: BlockColor([53, 48, 56]), }, ), ( "polished_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 73), + color: BlockColor([72, 72, 73]), }, ), ( "polished_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 73), + color: BlockColor([72, 72, 73]), }, ), ( "polished_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 73), + color: BlockColor([72, 72, 73]), }, ), ( "polished_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 73), + color: BlockColor([72, 72, 73]), }, ), ( "polished_diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 193, 194), + color: BlockColor([192, 193, 194]), }, ), ( "polished_diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 193, 194), + color: BlockColor([192, 193, 194]), }, ), ( "polished_diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 193, 194), + color: BlockColor([192, 193, 194]), }, ), ( "polished_granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 106, 89), + color: BlockColor([154, 106, 89]), }, ), ( "polished_granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 106, 89), + color: BlockColor([154, 106, 89]), }, ), ( "polished_granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 106, 89), + color: BlockColor([154, 106, 89]), }, ), ( "poppy", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "potatoes", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(84, 135, 47), + color: BlockColor([84, 135, 47]), }, ), ( "potted_acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(118, 117, 23), + color: BlockColor([118, 117, 23]), }, ), ( "potted_allium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(158, 137, 183), + color: BlockColor([158, 137, 183]), }, ), ( "potted_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(101, 124, 47), + color: BlockColor([101, 124, 47]), }, ), ( "potted_azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(169, 204, 127), + color: BlockColor([169, 204, 127]), }, ), ( "potted_bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 144, 19), + color: BlockColor([93, 144, 19]), }, ), ( "potted_birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 160, 79), + color: BlockColor([127, 160, 79]), }, ), ( "potted_blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 162, 168), + color: BlockColor([47, 162, 168]), }, ), ( "potted_brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(153, 116, 92), + color: BlockColor([153, 116, 92]), }, ), ( "potted_cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(85, 127, 43), + color: BlockColor([85, 127, 43]), }, ), ( "potted_cornflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 121, 146), + color: BlockColor([79, 121, 146]), }, ), ( "potted_crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(141, 44, 29), + color: BlockColor([141, 44, 29]), }, ), ( "potted_crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 8, 41), + color: BlockColor([127, 8, 41]), }, ), ( "potted_dandelion", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(147, 172, 43), + color: BlockColor([147, 172, 43]), }, ), ( "potted_dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(61, 90, 30), + color: BlockColor([61, 90, 30]), }, ), ( "potted_dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(107, 78, 40), + color: BlockColor([107, 78, 40]), }, ), ( "potted_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(124, 124, 124), + color: BlockColor([124, 124, 124]), }, ), ( "potted_flowering_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(112, 121, 64), + color: BlockColor([112, 121, 64]), }, ), ( "potted_jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 81, 16), + color: BlockColor([47, 81, 16]), }, ), ( "potted_lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(123, 174, 95), + color: BlockColor([123, 174, 95]), }, ), ( "potted_mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(96, 174, 83), + color: BlockColor([96, 174, 83]), }, ), ( "potted_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(77, 106, 40), + color: BlockColor([77, 106, 40]), }, ), ( "potted_orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 142, 30), + color: BlockColor([93, 142, 30]), }, ), ( "potted_oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(179, 202, 143), + color: BlockColor([179, 202, 143]), }, ), ( "potted_pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 157, 78), + color: BlockColor([99, 157, 78]), }, ), ( "potted_poppy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(128, 64, 37), + color: BlockColor([128, 64, 37]), }, ), ( "potted_red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(216, 75, 67), + color: BlockColor([216, 75, 67]), }, ), ( "potted_red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(89, 128, 32), + color: BlockColor([89, 128, 32]), }, ), ( "potted_spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 60, 36), + color: BlockColor([44, 60, 36]), }, ), ( "potted_warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(74, 109, 87), + color: BlockColor([74, 109, 87]), }, ), ( "potted_warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 136, 123), + color: BlockColor([20, 136, 123]), }, ), ( "potted_white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(93, 164, 71), + color: BlockColor([93, 164, 71]), }, ), ( "potted_wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(41, 44, 23), + color: BlockColor([41, 44, 23]), }, ), ( "powder_snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 253, 253), + color: BlockColor([248, 253, 253]), }, ), ( "powder_snow_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 72, 74), + color: BlockColor([73, 72, 74]), }, ), ( "powered_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 109, 74), + color: BlockColor([137, 109, 74]), }, ), ( "prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 156, 151), + color: BlockColor([99, 156, 151]), }, ), ( "prismarine_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 171, 158), + color: BlockColor([99, 171, 158]), }, ), ( "prismarine_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 171, 158), + color: BlockColor([99, 171, 158]), }, ), ( "prismarine_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 171, 158), + color: BlockColor([99, 171, 158]), }, ), ( "prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 156, 151), + color: BlockColor([99, 156, 151]), }, ), ( "prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 156, 151), + color: BlockColor([99, 156, 151]), }, ), ( "prismarine_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(99, 156, 151), + color: BlockColor([99, 156, 151]), }, ), ( "pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(198, 118, 24), + color: BlockColor([198, 118, 24]), }, ), ( "pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(154, 154, 154), + color: BlockColor([154, 154, 154]), }, ), ( "purple_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "purple_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "purple_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "purple_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "purple_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(121, 42, 172), + color: BlockColor([121, 42, 172]), }, ), ( "purple_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(100, 31, 156), + color: BlockColor([100, 31, 156]), }, ), ( "purple_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 55, 177), + color: BlockColor([131, 55, 177]), }, ), ( "purple_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 48, 152), + color: BlockColor([109, 48, 152]), }, ), ( "purple_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 32, 156), + color: BlockColor([103, 32, 156]), }, ), ( "purple_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(127, 63, 178), + color: BlockColor([127, 63, 178]), }, ), ( "purple_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 61, 171), + color: BlockColor([122, 61, 171]), }, ), ( "purple_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(118, 70, 86), + color: BlockColor([118, 70, 86]), }, ), ( "purple_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "purple_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(121, 42, 172), + color: BlockColor([121, 42, 172]), }, ), ( "purpur_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(169, 125, 169), + color: BlockColor([169, 125, 169]), }, ), ( "purpur_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(171, 129, 171), + color: BlockColor([171, 129, 171]), }, ), ( "purpur_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(169, 125, 169), + color: BlockColor([169, 125, 169]), }, ), ( "purpur_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(169, 125, 169), + color: BlockColor([169, 125, 169]), }, ), ( "quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "quartz_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(234, 229, 221), + color: BlockColor([234, 229, 221]), }, ), ( "quartz_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 230, 224), + color: BlockColor([235, 230, 224]), }, ), ( "quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 111, 88), + color: BlockColor([125, 111, 88]), }, ), ( "raw_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 105, 79), + color: BlockColor([154, 105, 79]), }, ), ( "raw_gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(221, 169, 46), + color: BlockColor([221, 169, 46]), }, ), ( "raw_iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(166, 135, 107), + color: BlockColor([166, 135, 107]), }, ), ( "red_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "red_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 39, 34), + color: BlockColor([160, 39, 34]), }, ), ( "red_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 32, 32), + color: BlockColor([142, 32, 32]), }, ), ( "red_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(168, 54, 50), + color: BlockColor([168, 54, 50]), }, ), ( "red_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 59, 53), + color: BlockColor([181, 59, 53]), }, ), ( "red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(200, 46, 45), + color: BlockColor([200, 46, 45]), }, ), ( "red_nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(69, 7, 9), + color: BlockColor([69, 7, 9]), }, ), ( "red_nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(69, 7, 9), + color: BlockColor([69, 7, 9]), }, ), ( "red_nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(69, 7, 9), + color: BlockColor([69, 7, 9]), }, ), ( "red_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(69, 7, 9), + color: BlockColor([69, 7, 9]), }, ), ( "red_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(190, 102, 33), + color: BlockColor([190, 102, 33]), }, ), ( "red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "red_sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "red_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(140, 31, 30), + color: BlockColor([140, 31, 30]), }, ), ( "red_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(153, 51, 51), + color: BlockColor([153, 51, 51]), }, ), ( "red_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(147, 48, 48), + color: BlockColor([147, 48, 48]), }, ), ( "red_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(143, 61, 46), + color: BlockColor([143, 61, 46]), }, ), ( "red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "red_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 39, 34), + color: BlockColor([160, 39, 34]), }, ), ( "redstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(175, 24, 5), + color: BlockColor([175, 24, 5]), }, ), ( "redstone_lamp", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(95, 54, 30), + color: BlockColor([95, 54, 30]), }, ), ( "redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(140, 109, 109), + color: BlockColor([140, 109, 109]), }, ), ( "redstone_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "redstone_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "redstone_wire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(175, 24, 5), + color: BlockColor([175, 24, 5]), }, ), ( "reinforced_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 82, 78), + color: BlockColor([80, 82, 78]), }, ), ( "repeater", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 157, 156), + color: BlockColor([160, 157, 156]), }, ), ( "repeating_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(129, 111, 176), + color: BlockColor([129, 111, 176]), }, ), ( "respawn_anchor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(75, 26, 144), + color: BlockColor([75, 26, 144]), }, ), ( "rooted_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(144, 103, 76), + color: BlockColor([144, 103, 76]), }, ), ( "rose_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(131, 66, 37), + color: BlockColor([131, 66, 37]), }, ), ( "sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(219, 207, 163), + color: BlockColor([219, 207, 163]), }, ), ( "sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "scaffolding", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(174, 134, 80), + color: BlockColor([174, 134, 80]), }, ), ( "sculk", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(12, 29, 36), + color: BlockColor([12, 29, 36]), }, ), ( "sculk_catalyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(15, 31, 38), + color: BlockColor([15, 31, 38]), }, ), ( "sculk_sensor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(7, 70, 84), + color: BlockColor([7, 70, 84]), }, ), ( "sculk_shrieker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(198, 205, 169), + color: BlockColor([198, 205, 169]), }, ), ( "sculk_vein", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(7, 48, 57), + color: BlockColor([7, 48, 57]), }, ), ( "sea_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(172, 199, 190), + color: BlockColor([172, 199, 190]), }, ), ( "sea_pickle", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(90, 97, 39), + color: BlockColor([90, 97, 39]), }, ), ( "seagrass", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "shroomlight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(240, 146, 70), + color: BlockColor([240, 146, 70]), }, ), ( "shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(139, 96, 139), + color: BlockColor([139, 96, 139]), }, ), ( "sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "slime_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(111, 192, 91), + color: BlockColor([111, 192, 91]), }, ), ( "small_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "small_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "smithing_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(57, 58, 70), + color: BlockColor([57, 58, 70]), }, ), ( "smoker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(85, 83, 81), + color: BlockColor([85, 83, 81]), }, ), ( "smooth_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 72, 78), + color: BlockColor([72, 72, 78]), }, ), ( "smooth_quartz", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "smooth_quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "smooth_quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(235, 229, 222), + color: BlockColor([235, 229, 222]), }, ), ( "smooth_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "smooth_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "smooth_red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(181, 97, 31), + color: BlockColor([181, 97, 31]), }, ), ( "smooth_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "smooth_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "smooth_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(223, 214, 170), + color: BlockColor([223, 214, 170]), }, ), ( "smooth_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(158, 158, 158), + color: BlockColor([158, 158, 158]), }, ), ( "smooth_stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(158, 158, 158), + color: BlockColor([158, 158, 158]), }, ), ( "snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(249, 254, 254), + color: BlockColor([249, 254, 254]), }, ), ( "snow_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(249, 254, 254), + color: BlockColor([249, 254, 254]), }, ), ( "soul_campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(80, 204, 208), + color: BlockColor([80, 204, 208]), }, ), ( "soul_fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(51, 192, 197), + color: BlockColor([51, 192, 197]), }, ), ( "soul_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(71, 99, 114), + color: BlockColor([71, 99, 114]), }, ), ( "soul_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(81, 62, 50), + color: BlockColor([81, 62, 50]), }, ), ( "soul_soil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(75, 57, 46), + color: BlockColor([75, 57, 46]), }, ), ( "soul_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "soul_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "spawner", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(36, 46, 62), + color: BlockColor([36, 46, 62]), }, ), ( "sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(195, 192, 74), + color: BlockColor([195, 192, 74]), }, ), ( "spore_blossom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(206, 96, 158), + color: BlockColor([206, 96, 158]), }, ), ( "spruce_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "spruce_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(106, 80, 48), + color: BlockColor([106, 80, 48]), }, ), ( "spruce_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), - color: BlockColor(126, 126, 126), + color: BlockColor([126, 126, 126]), }, ), ( "spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(108, 80, 46), + color: BlockColor([108, 80, 46]), }, ), ( "spruce_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 60, 36), + color: BlockColor([44, 60, 36]), }, ), ( "spruce_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(114, 84, 48), + color: BlockColor([114, 84, 48]), }, ), ( "spruce_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(103, 79, 47), + color: BlockColor([103, 79, 47]), }, ), ( "spruce_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(58, 37, 16), + color: BlockColor([58, 37, 16]), }, ), ( "sticky_piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 104, 96), + color: BlockColor([109, 104, 96]), }, ), ( "stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 121, 122), + color: BlockColor([122, 121, 122]), }, ), ( "stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 121, 122), + color: BlockColor([122, 121, 122]), }, ), ( "stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 121, 122), + color: BlockColor([122, 121, 122]), }, ), ( "stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(122, 121, 122), + color: BlockColor([122, 121, 122]), }, ), ( "stone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "stone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "stone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(125, 125, 125), + color: BlockColor([125, 125, 125]), }, ), ( "stonecutter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(123, 118, 111), + color: BlockColor([123, 118, 111]), }, ), ( "stripped_acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(166, 91, 51), + color: BlockColor([166, 91, 51]), }, ), ( "stripped_acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(174, 92, 59), + color: BlockColor([174, 92, 59]), }, ), ( "stripped_birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 171, 116), + color: BlockColor([191, 171, 116]), }, ), ( "stripped_birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(196, 176, 118), + color: BlockColor([196, 176, 118]), }, ), ( "stripped_crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(137, 57, 90), + color: BlockColor([137, 57, 90]), }, ), ( "stripped_crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(121, 56, 82), + color: BlockColor([121, 56, 82]), }, ), ( "stripped_dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(65, 44, 22), + color: BlockColor([65, 44, 22]), }, ), ( "stripped_dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(72, 56, 36), + color: BlockColor([72, 56, 36]), }, ), ( "stripped_jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(165, 122, 81), + color: BlockColor([165, 122, 81]), }, ), ( "stripped_jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(171, 132, 84), + color: BlockColor([171, 132, 84]), }, ), ( "stripped_mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 43, 43), + color: BlockColor([109, 43, 43]), }, ), ( "stripped_mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(119, 54, 47), + color: BlockColor([119, 54, 47]), }, ), ( "stripped_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(160, 129, 77), + color: BlockColor([160, 129, 77]), }, ), ( "stripped_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(177, 144, 86), + color: BlockColor([177, 144, 86]), }, ), ( "stripped_spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(105, 80, 46), + color: BlockColor([105, 80, 46]), }, ), ( "stripped_spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(115, 89, 52), + color: BlockColor([115, 89, 52]), }, ), ( "stripped_warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(57, 150, 147), + color: BlockColor([57, 150, 147]), }, ), ( "stripped_warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(52, 128, 124), + color: BlockColor([52, 128, 124]), }, ), ( "structure_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(88, 74, 90), + color: BlockColor([88, 74, 90]), }, ), ( "structure_void", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "sugar_cane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(148, 192, 101), + color: BlockColor([148, 192, 101]), }, ), ( "sunflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(246, 196, 54), + color: BlockColor([246, 196, 54]), }, ), ( "sweet_berry_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(68, 77, 50), + color: BlockColor([68, 77, 50]), }, ), ( "tall_grass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(151, 149, 151), + color: BlockColor([151, 149, 151]), }, ), ( "tall_seagrass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(59, 139, 14), + color: BlockColor([59, 139, 14]), }, ), ( "target", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(226, 170, 157), + color: BlockColor([226, 170, 157]), }, ), ( "terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(152, 94, 67), + color: BlockColor([152, 94, 67]), }, ), ( "tinted_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 38, 46), + color: BlockColor([44, 38, 46]), }, ), ( "tnt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(142, 62, 53), + color: BlockColor([142, 62, 53]), }, ), ( "torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "trapped_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(162, 130, 78), + color: BlockColor([162, 130, 78]), }, ), ( "tripwire", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "tripwire_hook", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(49, 87, 206), + color: BlockColor([49, 87, 206]), }, ), ( "tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "tuff", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(108, 109, 102), + color: BlockColor([108, 109, 102]), }, ), ( "turtle_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(228, 226, 191), + color: BlockColor([228, 226, 191]), }, ), ( "twisting_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 143, 124), + color: BlockColor([20, 143, 124]), }, ), ( "twisting_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 135, 122), + color: BlockColor([20, 135, 122]), }, ), ( "verdant_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(229, 244, 228), + color: BlockColor([229, 244, 228]), }, ), ( "vine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor(116, 116, 116), + color: BlockColor([116, 116, 116]), }, ), ( "void_air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "warped_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "warped_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(44, 126, 120), + color: BlockColor([44, 126, 120]), }, ), ( "warped_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(58, 58, 77), + color: BlockColor([58, 58, 77]), }, ), ( "warped_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 114, 101), + color: BlockColor([43, 114, 101]), }, ), ( "warped_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(20, 138, 124), + color: BlockColor([20, 138, 124]), }, ), ( "warped_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(43, 104, 99), + color: BlockColor([43, 104, 99]), }, ), ( "warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(53, 109, 110), + color: BlockColor([53, 109, 110]), }, ), ( "warped_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(47, 119, 111), + color: BlockColor([47, 119, 111]), }, ), ( "warped_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "warped_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(22, 119, 121), + color: BlockColor([22, 119, 121]), }, ), ( "water", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: BlockColor(177, 177, 177), + color: BlockColor([177, 177, 177]), }, ), ( "water_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(73, 72, 74), + color: BlockColor([73, 72, 74]), }, ), ( "waxed_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(192, 107, 79), + color: BlockColor([192, 107, 79]), }, ), ( "waxed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "waxed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "waxed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(191, 106, 80), + color: BlockColor([191, 106, 80]), }, ), ( "waxed_exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(161, 125, 103), + color: BlockColor([161, 125, 103]), }, ), ( "waxed_exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "waxed_exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "waxed_exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(154, 121, 101), + color: BlockColor([154, 121, 101]), }, ), ( "waxed_oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(82, 162, 132), + color: BlockColor([82, 162, 132]), }, ), ( "waxed_oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "waxed_oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "waxed_oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(79, 153, 126), + color: BlockColor([79, 153, 126]), }, ), ( "waxed_weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(108, 153, 110), + color: BlockColor([108, 153, 110]), }, ), ( "waxed_weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "waxed_weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "waxed_weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(108, 153, 110), + color: BlockColor([108, 153, 110]), }, ), ( "weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(109, 145, 107), + color: BlockColor([109, 145, 107]), }, ), ( "weeping_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(104, 1, 0), + color: BlockColor([104, 1, 0]), }, ), ( "weeping_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(132, 16, 12), + color: BlockColor([132, 16, 12]), }, ), ( "wet_sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(171, 181, 70), + color: BlockColor([171, 181, 70]), }, ), ( "wheat", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(166, 151, 73), + color: BlockColor([166, 151, 73]), }, ), ( "white_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "white_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "white_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "white_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "white_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(233, 236, 236), + color: BlockColor([233, 236, 236]), }, ), ( "white_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(207, 213, 214), + color: BlockColor([207, 213, 214]), }, ), ( "white_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(225, 227, 227), + color: BlockColor([225, 227, 227]), }, ), ( "white_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(188, 212, 202), + color: BlockColor([188, 212, 202]), }, ), ( "white_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(215, 220, 221), + color: BlockColor([215, 220, 221]), }, ), ( "white_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(255, 255, 255), + color: BlockColor([255, 255, 255]), }, ), ( "white_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(246, 246, 246), + color: BlockColor([246, 246, 246]), }, ), ( "white_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(209, 178, 161), + color: BlockColor([209, 178, 161]), }, ), ( "white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "white_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "white_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(233, 236, 236), + color: BlockColor([233, 236, 236]), }, ), ( "wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "wither_skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "wither_skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "yellow_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "yellow_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "yellow_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "yellow_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 222, 214), + color: BlockColor([248, 222, 214]), }, ), ( "yellow_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 197, 39), + color: BlockColor([248, 197, 39]), }, ), ( "yellow_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(240, 175, 21), + color: BlockColor([240, 175, 21]), }, ), ( "yellow_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(232, 199, 54), + color: BlockColor([232, 199, 54]), }, ), ( "yellow_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(234, 192, 88), + color: BlockColor([234, 192, 88]), }, ), ( "yellow_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 188, 29), + color: BlockColor([248, 188, 29]), }, ), ( "yellow_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(229, 229, 51), + color: BlockColor([229, 229, 51]), }, ), ( "yellow_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(221, 221, 48), + color: BlockColor([221, 221, 48]), }, ), ( "yellow_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(186, 133, 35), + color: BlockColor([186, 133, 35]), }, ), ( "yellow_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "yellow_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor(248, 197, 39), + color: BlockColor([248, 197, 39]), }, ), ( "zombie_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ( "zombie_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor(0, 0, 0), + color: BlockColor([0, 0, 0]), }, ), ]; diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 8bad34f..672daa0 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -34,7 +34,7 @@ where } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct BlockColor(pub u8, pub u8, pub u8); +pub struct BlockColor(pub [u8; 3]); #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockType { From bcec704d27670c6bb673bddaba2f46548ddf5cd1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 4 Mar 2023 21:45:59 +0100 Subject: [PATCH 144/460] main: add height-based color modification Modify terrain color depending on the height to give a sense of elevation. --- src/main.rs | 25 +++++++++++++++++++------ src/world/layer.rs | 2 +- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 14589f4..a0afa43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,10 @@ use minedmap::{ io::storage, resource, types::*, - world::{self, layer::BlockLightArray}, + world::{ + self, + layer::{BlockInfo, BlockLightArray}, + }, }; #[derive(Debug, Parser)] @@ -275,6 +278,19 @@ impl<'a> TileRenderer<'a> { storage::read(&processed_path).context("Failed to load processed region data") } + fn block_color(block: &BlockInfo) -> [u8; 4] { + let h = block + .depth + .map(|depth| 0.5 + 0.005 * depth.0 as f32) + .unwrap_or_default(); + let c = block + .block_type + .color + .0 + .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); + [c[0], c[1], c[2], 255] + } + fn render_chunk( image: &mut image::RgbaImage, coords: ChunkCoords, @@ -284,14 +300,11 @@ impl<'a> TileRenderer<'a> { let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { image::Rgba( - match chunk[LayerBlockCoords { + match &chunk[LayerBlockCoords { x: BlockX(x as u8), z: BlockZ(z as u8), }] { - Some(block) => { - let c = block.block_type.color.0; - [c[0], c[1], c[2], 255] - } + Some(block) => Self::block_color(block), None => [0, 0, 0, 0], }, ) diff --git a/src/world/layer.rs b/src/world/layer.rs index 4036f4a..fd24790 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -8,7 +8,7 @@ use crate::{ }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -pub struct BlockHeight(i32); +pub struct BlockHeight(pub i32); impl BlockHeight { /// Constructs a new [BlockHeight] from section and block Y indices From e62e19796c5996eaccea6d60cc9790becc770077 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 1 Apr 2023 16:15:29 +0200 Subject: [PATCH 145/460] Update dependencies --- Cargo.lock | 276 +++++++++++++++++++++++++++-------------------------- 1 file changed, 139 insertions(+), 137 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dda9b5c..4ca24e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,10 +9,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "anyhow" -version = "1.0.69" +name = "anstream" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" [[package]] name = "autocfg" @@ -37,9 +77,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bytemuck" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" [[package]] name = "byteorder" @@ -70,46 +110,51 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.6" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", - "clap_lex", - "is-terminal", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.12", ] [[package]] name = "clap_lex" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "cmake" -version = "0.1.49" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" dependencies = [ "cc", ] @@ -120,6 +165,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +dependencies = [ + "windows-sys", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -152,18 +212,18 @@ checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -178,9 +238,9 @@ dependencies = [ [[package]] name = "fastnbt" -version = "2.3.2" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da8cfe3db6e587f39487b01dae75222c5fa809342f6aa4b8310d17b53e666728" +checksum = "f1aab2b0109236f6c89cc81b9e2ef4aced6d585aabe96ac860ee5e9a102eb198" dependencies = [ "byteorder", "cesu8", @@ -213,9 +273,9 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "image" -version = "0.24.5" +version = "0.24.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" dependencies = [ "bytemuck", "byteorder", @@ -227,19 +287,20 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" dependencies = [ + "hermit-abi", "libc", "windows-sys", ] [[package]] name = "is-terminal" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi", "io-lifetimes", @@ -258,18 +319,18 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libz-ng-sys" @@ -283,9 +344,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "minedmap" @@ -350,12 +411,6 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "pkg-config" version = "0.3.26" @@ -374,53 +429,29 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] [[package]] name = "rustix" -version = "0.36.8" +version = "0.37.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" dependencies = [ "bitflags", "errno", @@ -432,9 +463,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] @@ -450,13 +481,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.12", ] [[package]] @@ -477,56 +508,27 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.2.0" +name = "syn" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" dependencies = [ - "winapi-util", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "windows-sys" @@ -539,9 +541,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -554,45 +556,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "zstd" From f2b7808e8495e9a16388046ed0d8073803fb5132 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Apr 2023 15:10:40 +0200 Subject: [PATCH 146/460] world: distinguish pre-v1.18 biome data structures --- src/world/chunk.rs | 7 +++---- src/world/section.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 10efc6a..a9a5c6b 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -24,14 +24,14 @@ pub enum Chunk<'a> { /// block IDs V1_13 { section_map: BTreeMap, BlockLight<'a>)>, - biomes: &'a de::BiomesV0, + biomes: BiomesV0<'a>, }, /// Original pre-1.13 chunk /// /// The original chunk format with fixed 8-bit numeric block IDs V0 { section_map: BTreeMap, BlockLight<'a>)>, - biomes: &'a de::BiomesV0, + biomes: BiomesV0<'a>, }, /// Unpopulated chunk without any block data Empty, @@ -158,8 +158,7 @@ impl<'a> Chunk<'a> { } } - // TODO Check biomes length - let biomes = level.biomes.as_ref().context("Invalid biome data"); + let biomes = BiomesV0::new(level.biomes.as_ref()); Ok( match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { diff --git a/src/world/section.rs b/src/world/section.rs index d3c590a..1aa8b7f 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -202,6 +202,36 @@ impl<'a> BiomesV18<'a> { } } +/// Pre-v1.18 section biome data +/// +/// There are a 3 formats for biome data that were used in +/// different pre-v1.18 Minecraft versions +#[derive(Debug)] +pub enum BiomesV0<'a> { + IntArrayV15(&'a fastnbt::IntArray), + IntArrayV0(&'a fastnbt::IntArray), + ByteArray(&'a fastnbt::ByteArray), +} + +impl<'a> BiomesV0<'a> { + /// Constructs a new [BiomesV0] from deserialized data structures + pub fn new(biomes: Option<&'a de::BiomesV0>) -> Result { + const N: usize = BLOCKS_PER_CHUNK; + const MAXY: usize = 256; + const BN: usize = N >> 2; + const BMAXY: usize = MAXY >> 2; + + Ok(match biomes { + Some(de::BiomesV0::IntArray(data)) if data.len() == BN * BN * BMAXY => { + BiomesV0::IntArrayV15(data) + } + Some(de::BiomesV0::IntArray(data)) if data.len() == N * N => BiomesV0::IntArrayV0(data), + Some(de::BiomesV0::ByteArray(data)) if data.len() == N * N => BiomesV0::ByteArray(data), + _ => bail!("Invalid biome data"), + }) + } +} + #[derive(Debug, Clone, Copy)] pub struct BlockLight<'a>(Option<&'a [i8]>); From e462e17ee24dd99da20bb9c5029d8291410b50d0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 5 Apr 2023 20:05:59 +0200 Subject: [PATCH 147/460] resource: rename BlockColor to Color The same struct will be used for biomes. --- resource/generate.py | 2 +- src/resource/block_types.rs | 1876 +++++++++++++++++------------------ src/resource/mod.rs | 4 +- 3 files changed, 941 insertions(+), 941 deletions(-) diff --git a/resource/generate.py b/resource/generate.py index 4398ce4..fabff63 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -36,7 +36,7 @@ with open(sys.argv[2], 'w') as f: flags.append('Water') flags = 'make_bitflags!(BlockFlag::{' + '|'.join(flags) + '})' - print('\t("%s", BlockType { flags: %s, color: BlockColor([%u, %u, %u]) }),' % ( + print('\t("%s", BlockType { flags: %s, color: Color([%u, %u, %u]) }),' % ( name, flags, info['color']['r'], diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index 1520b8e..467cf7a 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -7,6566 +7,6566 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "acacia_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "acacia_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([167, 95, 60]), + color: Color([167, 95, 60]), }, ), ( "acacia_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor([149, 148, 148]), + color: Color([149, 148, 148]), }, ), ( "acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([150, 88, 55]), + color: Color([150, 88, 55]), }, ), ( "acacia_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([118, 117, 23]), + color: Color([118, 117, 23]), }, ), ( "acacia_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 90, 50]), + color: Color([168, 90, 50]), }, ), ( "acacia_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([156, 87, 51]), + color: Color([156, 87, 51]), }, ), ( "acacia_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 96, 86]), + color: Color([103, 96, 86]), }, ), ( "activator_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 87, 74]), + color: Color([115, 87, 74]), }, ), ( "air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "allium", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "amethyst_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([133, 97, 191]), + color: Color([133, 97, 191]), }, ), ( "amethyst_cluster", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([163, 126, 207]), + color: Color([163, 126, 207]), }, ), ( "ancient_debris", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([94, 66, 58]), + color: Color([94, 66, 58]), }, ), ( "andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 136, 136]), + color: Color([136, 136, 136]), }, ), ( "andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 136, 136]), + color: Color([136, 136, 136]), }, ), ( "andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 136, 136]), + color: Color([136, 136, 136]), }, ), ( "andesite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 136, 136]), + color: Color([136, 136, 136]), }, ), ( "anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 72]), + color: Color([72, 72, 72]), }, ), ( "attached_melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([141, 142, 141]), + color: Color([141, 142, 141]), }, ), ( "attached_pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([139, 139, 139]), + color: Color([139, 139, 139]), }, ), ( "azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 124, 47]), + color: Color([101, 124, 47]), }, ), ( "azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([90, 114, 44]), + color: Color([90, 114, 44]), }, ), ( "azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 144, 19]), + color: Color([93, 144, 19]), }, ), ( "bamboo_sapling", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "barrel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([134, 100, 58]), + color: Color([134, 100, 58]), }, ), ( "barrier", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 81, 86]), + color: Color([80, 81, 86]), }, ), ( "beacon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 220, 215]), + color: Color([117, 220, 215]), }, ), ( "bedrock", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([85, 85, 85]), + color: Color([85, 85, 85]), }, ), ( "bee_nest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([202, 160, 74]), + color: Color([202, 160, 74]), }, ), ( "beehive", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([180, 146, 90]), + color: Color([180, 146, 90]), }, ), ( "beetroots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 91, 30]), + color: Color([93, 91, 30]), }, ), ( "bell", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([253, 235, 110]), + color: Color([253, 235, 110]), }, ), ( "big_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([111, 141, 51]), + color: Color([111, 141, 51]), }, ), ( "big_dripleaf_stem", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "birch_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "birch_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([220, 209, 176]), + color: Color([220, 209, 176]), }, ), ( "birch_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Birch}), - color: BlockColor([130, 129, 130]), + color: Color([130, 129, 130]), }, ), ( "birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([193, 179, 135]), + color: Color([193, 179, 135]), }, ), ( "birch_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 160, 79]), + color: Color([127, 160, 79]), }, ), ( "birch_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 175, 121]), + color: Color([192, 175, 121]), }, ), ( "birch_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([207, 194, 157]), + color: Color([207, 194, 157]), }, ), ( "birch_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([216, 215, 210]), + color: Color([216, 215, 210]), }, ), ( "black_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "black_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "black_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "black_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "black_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 21, 25]), + color: Color([20, 21, 25]), }, ), ( "black_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([8, 10, 15]), + color: Color([8, 10, 15]), }, ), ( "black_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([25, 26, 31]), + color: Color([25, 26, 31]), }, ), ( "black_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([67, 30, 32]), + color: Color([67, 30, 32]), }, ), ( "black_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([25, 25, 29]), + color: Color([25, 25, 29]), }, ), ( "black_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([25, 25, 25]), + color: Color([25, 25, 25]), }, ), ( "black_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([24, 24, 24]), + color: Color([24, 24, 24]), }, ), ( "black_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([37, 22, 16]), + color: Color([37, 22, 16]), }, ), ( "black_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "black_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 21, 25]), + color: Color([20, 21, 25]), }, ), ( "blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([42, 36, 41]), + color: Color([42, 36, 41]), }, ), ( "blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([42, 36, 41]), + color: Color([42, 36, 41]), }, ), ( "blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([42, 36, 41]), + color: Color([42, 36, 41]), }, ), ( "blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([42, 36, 41]), + color: Color([42, 36, 41]), }, ), ( "blast_furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 80, 81]), + color: Color([80, 80, 81]), }, ), ( "blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 57, 157]), + color: Color([53, 57, 157]), }, ), ( "blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 46, 143]), + color: Color([44, 46, 143]), }, ), ( "blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 73, 166]), + color: Color([70, 73, 166]), }, ), ( "blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 64, 139]), + color: Color([47, 64, 139]), }, ), ( "blue_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([116, 167, 253]), + color: Color([116, 167, 253]), }, ), ( "blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 45, 140]), + color: Color([43, 45, 140]), }, ), ( "blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([51, 76, 178]), + color: Color([51, 76, 178]), }, ), ( "blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([48, 73, 171]), + color: Color([48, 73, 171]), }, ), ( "blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([74, 59, 91]), + color: Color([74, 59, 91]), }, ), ( "blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 57, 157]), + color: Color([53, 57, 157]), }, ), ( "bone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([209, 206, 179]), + color: Color([209, 206, 179]), }, ), ( "bookshelf", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([207, 91, 159]), + color: Color([207, 91, 159]), }, ), ( "brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brewing_stand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 100, 80]), + color: Color([122, 100, 80]), }, ), ( "brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([150, 97, 83]), + color: Color([150, 97, 83]), }, ), ( "brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([150, 97, 83]), + color: Color([150, 97, 83]), }, ), ( "brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([150, 97, 83]), + color: Color([150, 97, 83]), }, ), ( "bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([150, 97, 83]), + color: Color([150, 97, 83]), }, ), ( "brown_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brown_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brown_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brown_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "brown_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 71, 40]), + color: Color([114, 71, 40]), }, ), ( "brown_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([96, 59, 31]), + color: Color([96, 59, 31]), }, ), ( "brown_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 84, 53]), + color: Color([125, 84, 53]), }, ), ( "brown_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 106, 85]), + color: Color([119, 106, 85]), }, ), ( "brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brown_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 111, 81]), + color: Color([149, 111, 81]), }, ), ( "brown_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([106, 66, 35]), + color: Color([106, 66, 35]), }, ), ( "brown_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([102, 76, 51]), + color: Color([102, 76, 51]), }, ), ( "brown_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([97, 73, 48]), + color: Color([97, 73, 48]), }, ), ( "brown_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 51, 35]), + color: Color([77, 51, 35]), }, ), ( "brown_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "brown_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 71, 40]), + color: Color([114, 71, 40]), }, ), ( "bubble_column", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: BlockColor([177, 177, 177]), + color: Color([177, 177, 177]), }, ), ( "bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([165, 26, 162]), + color: Color([165, 26, 162]), }, ), ( "bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "budding_amethyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([132, 96, 186]), + color: Color([132, 96, 186]), }, ), ( "cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([85, 127, 43]), + color: Color([85, 127, 43]), }, ), ( "cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "calcite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 224, 220]), + color: Color([223, 224, 220]), }, ), ( "campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 88, 54]), + color: Color([110, 88, 54]), }, ), ( "candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "carrots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([81, 124, 37]), + color: Color([81, 124, 37]), }, ), ( "cartography_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 87, 67]), + color: Color([103, 87, 67]), }, ), ( "carved_pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([198, 118, 24]), + color: Color([198, 118, 24]), }, ), ( "cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 72, 74]), + color: Color([73, 72, 74]), }, ), ( "cave_air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cave_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([90, 109, 40]), + color: Color([90, 109, 40]), }, ), ( "cave_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([88, 101, 38]), + color: Color([88, 101, 38]), }, ), ( "chain", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "chain_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 161, 147]), + color: Color([131, 161, 147]), }, ), ( "chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "chipped_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 72]), + color: Color([72, 72, 72]), }, ), ( "chiseled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 54, 54]), + color: Color([54, 54, 54]), }, ), ( "chiseled_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 23, 28]), + color: Color([47, 23, 28]), }, ), ( "chiseled_polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "chiseled_quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([231, 226, 218]), + color: Color([231, 226, 218]), }, ), ( "chiseled_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "chiseled_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 118, 119]), + color: Color([119, 118, 119]), }, ), ( "chorus_flower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([151, 120, 151]), + color: Color([151, 120, 151]), }, ), ( "chorus_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 57, 93]), + color: Color([93, 57, 93]), }, ), ( "clay", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 166, 179]), + color: Color([160, 166, 179]), }, ), ( "coal_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([16, 15, 15]), + color: Color([16, 15, 15]), }, ), ( "coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([105, 105, 105]), + color: Color([105, 105, 105]), }, ), ( "coarse_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 85, 59]), + color: Color([119, 85, 59]), }, ), ( "cobbled_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 77, 80]), + color: Color([77, 77, 80]), }, ), ( "cobbled_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 77, 80]), + color: Color([77, 77, 80]), }, ), ( "cobbled_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 77, 80]), + color: Color([77, 77, 80]), }, ), ( "cobbled_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 77, 80]), + color: Color([77, 77, 80]), }, ), ( "cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 127, 127]), + color: Color([127, 127, 127]), }, ), ( "cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 127, 127]), + color: Color([127, 127, 127]), }, ), ( "cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 127, 127]), + color: Color([127, 127, 127]), }, ), ( "cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 127, 127]), + color: Color([127, 127, 127]), }, ), ( "cobweb", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([228, 233, 234]), + color: Color([228, 233, 234]), }, ), ( "cocoa", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 91, 40]), + color: Color([154, 91, 40]), }, ), ( "command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 136, 108]), + color: Color([181, 136, 108]), }, ), ( "comparator", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([166, 161, 159]), + color: Color([166, 161, 159]), }, ), ( "composter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([88, 61, 23]), + color: Color([88, 61, 23]), }, ), ( "conduit", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([159, 139, 113]), + color: Color([159, 139, 113]), }, ), ( "copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 107, 79]), + color: Color([192, 107, 79]), }, ), ( "copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([124, 125, 120]), + color: Color([124, 125, 120]), }, ), ( "cornflower", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cracked_deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([64, 64, 65]), + color: Color([64, 64, 65]), }, ), ( "cracked_deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([52, 52, 52]), + color: Color([52, 52, 52]), }, ), ( "cracked_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([40, 20, 23]), + color: Color([40, 20, 23]), }, ), ( "cracked_polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 37, 43]), + color: Color([44, 37, 43]), }, ), ( "cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([118, 117, 118]), + color: Color([118, 117, 118]), }, ), ( "crafting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 73, 42]), + color: Color([119, 73, 42]), }, ), ( "creeper_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "creeper_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "crimson_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "crimson_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 54, 79]), + color: Color([114, 54, 79]), }, ), ( "crimson_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([92, 25, 29]), + color: Color([92, 25, 29]), }, ), ( "crimson_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([130, 31, 31]), + color: Color([130, 31, 31]), }, ), ( "crimson_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([126, 8, 41]), + color: Color([126, 8, 41]), }, ), ( "crimson_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 48, 70]), + color: Color([101, 48, 70]), }, ), ( "crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 49, 70]), + color: Color([112, 49, 70]), }, ), ( "crimson_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 50, 72]), + color: Color([103, 50, 72]), }, ), ( "crimson_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "crying_obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([32, 10, 60]), + color: Color([32, 10, 60]), }, ), ( "cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "cut_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "cut_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "cut_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "cut_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "cyan_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cyan_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cyan_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cyan_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "cyan_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([21, 137, 145]), + color: Color([21, 137, 145]), }, ), ( "cyan_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([21, 119, 136]), + color: Color([21, 119, 136]), }, ), ( "cyan_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([36, 147, 157]), + color: Color([36, 147, 157]), }, ), ( "cyan_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([52, 118, 125]), + color: Color([52, 118, 125]), }, ), ( "cyan_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 121, 135]), + color: Color([20, 121, 135]), }, ), ( "cyan_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([76, 127, 153]), + color: Color([76, 127, 153]), }, ), ( "cyan_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 122, 147]), + color: Color([73, 122, 147]), }, ), ( "cyan_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([86, 91, 91]), + color: Color([86, 91, 91]), }, ), ( "cyan_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "cyan_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([21, 137, 145]), + color: Color([21, 137, 145]), }, ), ( "damaged_anvil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 72]), + color: Color([72, 72, 72]), }, ), ( "dandelion", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dark_oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dark_oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([76, 51, 25]), + color: Color([76, 51, 25]), }, ), ( "dark_oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor([150, 150, 150]), + color: Color([150, 150, 150]), }, ), ( "dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([67, 45, 22]), + color: Color([67, 45, 22]), }, ), ( "dark_oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([61, 90, 30]), + color: Color([61, 90, 30]), }, ), ( "dark_oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 43, 20]), + color: Color([66, 43, 20]), }, ), ( "dark_oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([75, 49, 23]), + color: Color([75, 49, 23]), }, ), ( "dark_oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([60, 46, 26]), + color: Color([60, 46, 26]), }, ), ( "dark_prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([51, 91, 75]), + color: Color([51, 91, 75]), }, ), ( "dark_prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([51, 91, 75]), + color: Color([51, 91, 75]), }, ), ( "dark_prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([51, 91, 75]), + color: Color([51, 91, 75]), }, ), ( "daylight_detector", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([130, 116, 94]), + color: Color([130, 116, 94]), }, ), ( "dead_brain_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_brain_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([124, 117, 114]), + color: Color([124, 117, 114]), }, ), ( "dead_brain_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_brain_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_bubble_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_bubble_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 123, 119]), + color: Color([131, 123, 119]), }, ), ( "dead_bubble_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_bubble_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([107, 78, 40]), + color: Color([107, 78, 40]), }, ), ( "dead_fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 123, 119]), + color: Color([131, 123, 119]), }, ), ( "dead_fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([133, 126, 122]), + color: Color([133, 126, 122]), }, ), ( "dead_horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([130, 123, 119]), + color: Color([130, 123, 119]), }, ), ( "dead_tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dead_tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 80, 82]), + color: Color([80, 80, 82]), }, ), ( "deepslate_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 70, 71]), + color: Color([70, 70, 71]), }, ), ( "deepslate_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 70, 71]), + color: Color([70, 70, 71]), }, ), ( "deepslate_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 70, 71]), + color: Color([70, 70, 71]), }, ), ( "deepslate_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 70, 71]), + color: Color([70, 70, 71]), }, ), ( "deepslate_coal_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([74, 74, 76]), + color: Color([74, 74, 76]), }, ), ( "deepslate_copper_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([92, 93, 89]), + color: Color([92, 93, 89]), }, ), ( "deepslate_diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([83, 106, 106]), + color: Color([83, 106, 106]), }, ), ( "deepslate_emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([78, 104, 87]), + color: Color([78, 104, 87]), }, ), ( "deepslate_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 102, 78]), + color: Color([115, 102, 78]), }, ), ( "deepslate_iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([106, 99, 94]), + color: Color([106, 99, 94]), }, ), ( "deepslate_lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 90, 115]), + color: Color([79, 90, 115]), }, ), ( "deepslate_redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([104, 73, 74]), + color: Color([104, 73, 74]), }, ), ( "deepslate_tile_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 54, 55]), + color: Color([54, 54, 55]), }, ), ( "deepslate_tile_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 54, 55]), + color: Color([54, 54, 55]), }, ), ( "deepslate_tile_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 54, 55]), + color: Color([54, 54, 55]), }, ), ( "deepslate_tiles", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 54, 55]), + color: Color([54, 54, 55]), }, ), ( "detector_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([123, 104, 90]), + color: Color([123, 104, 90]), }, ), ( "diamond_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([98, 237, 228]), + color: Color([98, 237, 228]), }, ), ( "diamond_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([121, 141, 140]), + color: Color([121, 141, 140]), }, ), ( "diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([188, 188, 188]), + color: Color([188, 188, 188]), }, ), ( "diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([188, 188, 188]), + color: Color([188, 188, 188]), }, ), ( "diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([188, 188, 188]), + color: Color([188, 188, 188]), }, ), ( "diorite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([188, 188, 188]), + color: Color([188, 188, 188]), }, ), ( "dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([134, 96, 67]), + color: Color([134, 96, 67]), }, ), ( "dirt_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([148, 121, 65]), + color: Color([148, 121, 65]), }, ), ( "dispenser", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 109, 109]), + color: Color([110, 109, 109]), }, ), ( "dragon_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([12, 9, 15]), + color: Color([12, 9, 15]), }, ), ( "dragon_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dragon_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "dried_kelp_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([50, 58, 38]), + color: Color([50, 58, 38]), }, ), ( "dripstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([134, 107, 92]), + color: Color([134, 107, 92]), }, ), ( "dropper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 109, 109]), + color: Color([110, 109, 109]), }, ), ( "emerald_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([42, 203, 87]), + color: Color([42, 203, 87]), }, ), ( "emerald_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([108, 136, 115]), + color: Color([108, 136, 115]), }, ), ( "enchanting_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([128, 75, 85]), + color: Color([128, 75, 85]), }, ), ( "end_gateway", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([15, 10, 24]), + color: Color([15, 10, 24]), }, ), ( "end_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([15, 10, 24]), + color: Color([15, 10, 24]), }, ), ( "end_portal_frame", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([91, 120, 97]), + color: Color([91, 120, 97]), }, ), ( "end_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "end_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([219, 222, 158]), + color: Color([219, 222, 158]), }, ), ( "end_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([218, 224, 162]), + color: Color([218, 224, 162]), }, ), ( "end_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([218, 224, 162]), + color: Color([218, 224, 162]), }, ), ( "end_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([218, 224, 162]), + color: Color([218, 224, 162]), }, ), ( "end_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([218, 224, 162]), + color: Color([218, 224, 162]), }, ), ( "ender_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([15, 10, 24]), + color: Color([15, 10, 24]), }, ), ( "exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([161, 125, 103]), + color: Color([161, 125, 103]), }, ), ( "exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "farmland", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([81, 44, 15]), + color: Color([81, 44, 15]), }, ), ( "fern", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([211, 140, 53]), + color: Color([211, 140, 53]), }, ), ( "fire_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "fire_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([163, 35, 46]), + color: Color([163, 35, 46]), }, ), ( "fire_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "fire_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "fletching_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([197, 180, 133]), + color: Color([197, 180, 133]), }, ), ( "flower_pot", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([124, 68, 53]), + color: Color([124, 68, 53]), }, ), ( "flowering_azalea", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 121, 64]), + color: Color([112, 121, 64]), }, ), ( "flowering_azalea_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 111, 60]), + color: Color([99, 111, 60]), }, ), ( "frogspawn", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([105, 90, 82]), + color: Color([105, 90, 82]), }, ), ( "frosted_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([140, 181, 252]), + color: Color([140, 181, 252]), }, ), ( "furnace", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 109, 109]), + color: Color([110, 109, 109]), }, ), ( "gilded_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([55, 42, 38]), + color: Color([55, 42, 38]), }, ), ( "glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([175, 213, 219]), + color: Color([175, 213, 219]), }, ), ( "glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([170, 210, 217]), + color: Color([170, 210, 217]), }, ), ( "glow_item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "glow_lichen", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "glowstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([171, 131, 84]), + color: Color([171, 131, 84]), }, ), ( "gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([246, 208, 61]), + color: Color([246, 208, 61]), }, ), ( "gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([145, 133, 106]), + color: Color([145, 133, 106]), }, ), ( "granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 103, 85]), + color: Color([149, 103, 85]), }, ), ( "granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 103, 85]), + color: Color([149, 103, 85]), }, ), ( "granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 103, 85]), + color: Color([149, 103, 85]), }, ), ( "granite_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 103, 85]), + color: Color([149, 103, 85]), }, ), ( "grass", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "grass_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([147, 147, 147]), + color: Color([147, 147, 147]), }, ), ( "grass_path", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([148, 121, 65]), + color: Color([148, 121, 65]), }, ), ( "gravel", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 127, 126]), + color: Color([131, 127, 126]), }, ), ( "gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([62, 68, 71]), + color: Color([62, 68, 71]), }, ), ( "gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([54, 57, 61]), + color: Color([54, 57, 61]), }, ), ( "gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([76, 81, 84]), + color: Color([76, 81, 84]), }, ), ( "gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([83, 90, 93]), + color: Color([83, 90, 93]), }, ), ( "gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([55, 58, 62]), + color: Color([55, 58, 62]), }, ), ( "gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([76, 76, 76]), + color: Color([76, 76, 76]), }, ), ( "gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 73, 73]), + color: Color([73, 73, 73]), }, ), ( "gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([57, 42, 35]), + color: Color([57, 42, 35]), }, ), ( "gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([62, 68, 71]), + color: Color([62, 68, 71]), }, ), ( "green_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "green_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "green_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "green_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "green_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([84, 109, 27]), + color: Color([84, 109, 27]), }, ), ( "green_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 91, 36]), + color: Color([73, 91, 36]), }, ), ( "green_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([97, 119, 44]), + color: Color([97, 119, 44]), }, ), ( "green_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 142, 67]), + color: Color([117, 142, 67]), }, ), ( "green_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 100, 31]), + color: Color([79, 100, 31]), }, ), ( "green_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([102, 127, 51]), + color: Color([102, 127, 51]), }, ), ( "green_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([97, 122, 48]), + color: Color([97, 122, 48]), }, ), ( "green_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([76, 83, 42]), + color: Color([76, 83, 42]), }, ), ( "green_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "green_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([84, 109, 27]), + color: Color([84, 109, 27]), }, ), ( "grindstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 142, 142]), + color: Color([142, 142, 142]), }, ), ( "hanging_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([161, 115, 91]), + color: Color([161, 115, 91]), }, ), ( "hay_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([165, 139, 12]), + color: Color([165, 139, 12]), }, ), ( "heavy_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([220, 220, 220]), + color: Color([220, 220, 220]), }, ), ( "honey_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([251, 185, 52]), + color: Color([251, 185, 52]), }, ), ( "honeycomb_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([229, 148, 29]), + color: Color([229, 148, 29]), }, ), ( "hopper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([75, 74, 75]), + color: Color([75, 74, 75]), }, ), ( "horn_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "horn_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([216, 199, 66]), + color: Color([216, 199, 66]), }, ), ( "horn_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "horn_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([145, 183, 253]), + color: Color([145, 183, 253]), }, ), ( "infested_chiseled_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 118, 119]), + color: Color([119, 118, 119]), }, ), ( "infested_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 127, 127]), + color: Color([127, 127, 127]), }, ), ( "infested_cracked_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([118, 117, 118]), + color: Color([118, 117, 118]), }, ), ( "infested_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 80, 82]), + color: Color([80, 80, 82]), }, ), ( "infested_mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 121, 105]), + color: Color([115, 121, 105]), }, ), ( "infested_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "infested_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 121, 122]), + color: Color([122, 121, 122]), }, ), ( "iron_bars", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 139, 135]), + color: Color([136, 139, 135]), }, ), ( "iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([220, 220, 220]), + color: Color([220, 220, 220]), }, ), ( "iron_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([194, 193, 193]), + color: Color([194, 193, 193]), }, ), ( "iron_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([136, 129, 122]), + color: Color([136, 129, 122]), }, ), ( "iron_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([202, 202, 202]), + color: Color([202, 202, 202]), }, ), ( "item_frame", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "jack_o_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([214, 152, 52]), + color: Color([214, 152, 52]), }, ), ( "jigsaw", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 69, 81]), + color: Color([80, 69, 81]), }, ), ( "jukebox", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 64, 47]), + color: Color([93, 64, 47]), }, ), ( "jungle_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "jungle_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([163, 119, 84]), + color: Color([163, 119, 84]), }, ), ( "jungle_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor([156, 154, 143]), + color: Color([156, 154, 143]), }, ), ( "jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 109, 70]), + color: Color([149, 109, 70]), }, ), ( "jungle_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 81, 16]), + color: Color([47, 81, 16]), }, ), ( "jungle_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 115, 80]), + color: Color([160, 115, 80]), }, ), ( "jungle_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([152, 110, 77]), + color: Color([152, 110, 77]), }, ), ( "jungle_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([85, 67, 25]), + color: Color([85, 67, 25]), }, ), ( "kelp", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "kelp_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([86, 130, 42]), + color: Color([86, 130, 42]), }, ), ( "ladder", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([106, 91, 83]), + color: Color([106, 91, 83]), }, ), ( "lapis_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([30, 67, 140]), + color: Color([30, 67, 140]), }, ), ( "lapis_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([107, 117, 141]), + color: Color([107, 117, 141]), }, ), ( "large_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "large_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "lava", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([212, 90, 18]), + color: Color([212, 90, 18]), }, ), ( "lava_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 72, 74]), + color: Color([73, 72, 74]), }, ), ( "lectern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([173, 137, 83]), + color: Color([173, 137, 83]), }, ), ( "lever", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_blue_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_blue_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_blue_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_blue_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "light_blue_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([58, 175, 217]), + color: Color([58, 175, 217]), }, ), ( "light_blue_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([35, 137, 198]), + color: Color([35, 137, 198]), }, ), ( "light_blue_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([74, 180, 213]), + color: Color([74, 180, 213]), }, ), ( "light_blue_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([94, 164, 208]), + color: Color([94, 164, 208]), }, ), ( "light_blue_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([49, 163, 212]), + color: Color([49, 163, 212]), }, ), ( "light_blue_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([102, 153, 216]), + color: Color([102, 153, 216]), }, ), ( "light_blue_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([97, 147, 208]), + color: Color([97, 147, 208]), }, ), ( "light_blue_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([113, 108, 137]), + color: Color([113, 108, 137]), }, ), ( "light_blue_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_blue_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([58, 175, 217]), + color: Color([58, 175, 217]), }, ), ( "light_gray_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_gray_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_gray_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_gray_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "light_gray_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 142, 134]), + color: Color([142, 142, 134]), }, ), ( "light_gray_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 115]), + color: Color([125, 125, 115]), }, ), ( "light_gray_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 154, 148]), + color: Color([154, 154, 148]), }, ), ( "light_gray_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([144, 166, 167]), + color: Color([144, 166, 167]), }, ), ( "light_gray_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([124, 124, 115]), + color: Color([124, 124, 115]), }, ), ( "light_gray_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([153, 153, 153]), + color: Color([153, 153, 153]), }, ), ( "light_gray_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([147, 147, 147]), + color: Color([147, 147, 147]), }, ), ( "light_gray_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([135, 106, 97]), + color: Color([135, 106, 97]), }, ), ( "light_gray_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "light_gray_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 142, 134]), + color: Color([142, 142, 134]), }, ), ( "light_weighted_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([246, 208, 61]), + color: Color([246, 208, 61]), }, ), ( "lightning_rod", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lilac", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 125, 147]), + color: Color([154, 125, 147]), }, ), ( "lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lily_pad", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([133, 133, 133]), + color: Color([133, 133, 133]), }, ), ( "lime_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lime_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lime_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lime_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "lime_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 185, 25]), + color: Color([112, 185, 25]), }, ), ( "lime_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([94, 168, 24]), + color: Color([94, 168, 24]), }, ), ( "lime_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 189, 41]), + color: Color([125, 189, 41]), }, ), ( "lime_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 197, 55]), + color: Color([162, 197, 55]), }, ), ( "lime_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 172, 23]), + color: Color([99, 172, 23]), }, ), ( "lime_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 204, 25]), + color: Color([127, 204, 25]), }, ), ( "lime_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 196, 24]), + color: Color([122, 196, 24]), }, ), ( "lime_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 117, 52]), + color: Color([103, 117, 52]), }, ), ( "lime_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "lime_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 185, 25]), + color: Color([112, 185, 25]), }, ), ( "lodestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([147, 149, 152]), + color: Color([147, 149, 152]), }, ), ( "loom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 119, 91]), + color: Color([142, 119, 91]), }, ), ( "magenta_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "magenta_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "magenta_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "magenta_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "magenta_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([189, 68, 179]), + color: Color([189, 68, 179]), }, ), ( "magenta_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([169, 48, 159]), + color: Color([169, 48, 159]), }, ), ( "magenta_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 83, 184]), + color: Color([192, 83, 184]), }, ), ( "magenta_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([208, 100, 191]), + color: Color([208, 100, 191]), }, ), ( "magenta_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([173, 54, 163]), + color: Color([173, 54, 163]), }, ), ( "magenta_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([178, 76, 216]), + color: Color([178, 76, 216]), }, ), ( "magenta_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([171, 73, 208]), + color: Color([171, 73, 208]), }, ), ( "magenta_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([149, 88, 108]), + color: Color([149, 88, 108]), }, ), ( "magenta_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "magenta_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([189, 68, 179]), + color: Color([189, 68, 179]), }, ), ( "magma_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 63, 31]), + color: Color([142, 63, 31]), }, ), ( "mangrove_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "mangrove_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 48, 46]), + color: Color([112, 48, 46]), }, ), ( "mangrove_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor([129, 128, 128]), + color: Color([129, 128, 128]), }, ), ( "mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([102, 48, 42]), + color: Color([102, 48, 42]), }, ), ( "mangrove_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([96, 174, 83]), + color: Color([96, 174, 83]), }, ), ( "mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([74, 59, 38]), + color: Color([74, 59, 38]), }, ), ( "mangrove_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 54, 48]), + color: Color([117, 54, 48]), }, ), ( "mangrove_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 46, 42]), + color: Color([110, 46, 42]), }, ), ( "mangrove_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([83, 66, 41]), + color: Color([83, 66, 41]), }, ), ( "medium_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "melon", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([111, 144, 30]), + color: Color([111, 144, 30]), }, ), ( "melon_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([153, 153, 153]), + color: Color([153, 153, 153]), }, ), ( "moss_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([89, 109, 45]), + color: Color([89, 109, 45]), }, ), ( "moss_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([89, 109, 45]), + color: Color([89, 109, 45]), }, ), ( "mossy_cobblestone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 118, 94]), + color: Color([110, 118, 94]), }, ), ( "mossy_cobblestone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 118, 94]), + color: Color([110, 118, 94]), }, ), ( "mossy_cobblestone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 118, 94]), + color: Color([110, 118, 94]), }, ), ( "mossy_cobblestone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([110, 118, 94]), + color: Color([110, 118, 94]), }, ), ( "mossy_stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 121, 105]), + color: Color([115, 121, 105]), }, ), ( "mossy_stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 121, 105]), + color: Color([115, 121, 105]), }, ), ( "mossy_stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 121, 105]), + color: Color([115, 121, 105]), }, ), ( "mossy_stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 121, 105]), + color: Color([115, 121, 105]), }, ), ( "moving_piston", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([60, 57, 60]), + color: Color([60, 57, 60]), }, ), ( "mud_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 103, 79]), + color: Color([137, 103, 79]), }, ), ( "mud_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 103, 79]), + color: Color([137, 103, 79]), }, ), ( "mud_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 103, 79]), + color: Color([137, 103, 79]), }, ), ( "mud_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 103, 79]), + color: Color([137, 103, 79]), }, ), ( "muddy_mangrove_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([70, 58, 45]), + color: Color([70, 58, 45]), }, ), ( "mushroom_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([203, 196, 185]), + color: Color([203, 196, 185]), }, ), ( "mycelium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([111, 98, 101]), + color: Color([111, 98, 101]), }, ), ( "nether_brick_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 21, 26]), + color: Color([44, 21, 26]), }, ), ( "nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 21, 26]), + color: Color([44, 21, 26]), }, ), ( "nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 21, 26]), + color: Color([44, 21, 26]), }, ), ( "nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 21, 26]), + color: Color([44, 21, 26]), }, ), ( "nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 21, 26]), + color: Color([44, 21, 26]), }, ), ( "nether_gold_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 54, 42]), + color: Color([115, 54, 42]), }, ), ( "nether_portal", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([89, 11, 192]), + color: Color([89, 11, 192]), }, ), ( "nether_quartz_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([117, 65, 62]), + color: Color([117, 65, 62]), }, ), ( "nether_sprouts", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([19, 151, 133]), + color: Color([19, 151, 133]), }, ), ( "nether_wart", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([111, 18, 19]), + color: Color([111, 18, 19]), }, ), ( "nether_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 2, 2]), + color: Color([114, 2, 2]), }, ), ( "netherite_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([66, 61, 63]), + color: Color([66, 61, 63]), }, ), ( "netherrack", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([97, 38, 38]), + color: Color([97, 38, 38]), }, ), ( "note_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([88, 58, 40]), + color: Color([88, 58, 40]), }, ), ( "oak_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "oak_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([140, 110, 66]), + color: Color([140, 110, 66]), }, ), ( "oak_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Foliage}), - color: BlockColor([144, 144, 144]), + color: Color([144, 144, 144]), }, ), ( "oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([151, 121, 73]), + color: Color([151, 121, 73]), }, ), ( "oak_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 106, 40]), + color: Color([77, 106, 40]), }, ), ( "oak_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "oak_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([124, 99, 56]), + color: Color([124, 99, 56]), }, ), ( "oak_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 85, 50]), + color: Color([109, 85, 50]), }, ), ( "observer", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([98, 98, 98]), + color: Color([98, 98, 98]), }, ), ( "obsidian", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([15, 10, 24]), + color: Color([15, 10, 24]), }, ), ( "ochre_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([250, 245, 206]), + color: Color([250, 245, 206]), }, ), ( "orange_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "orange_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "orange_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "orange_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "orange_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([240, 118, 19]), + color: Color([240, 118, 19]), }, ), ( "orange_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([224, 97, 0]), + color: Color([224, 97, 0]), }, ), ( "orange_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([227, 131, 31]), + color: Color([227, 131, 31]), }, ), ( "orange_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 147, 91]), + color: Color([154, 147, 91]), }, ), ( "orange_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([234, 106, 8]), + color: Color([234, 106, 8]), }, ), ( "orange_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([216, 127, 51]), + color: Color([216, 127, 51]), }, ), ( "orange_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([208, 122, 48]), + color: Color([208, 122, 48]), }, ), ( "orange_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([161, 83, 37]), + color: Color([161, 83, 37]), }, ), ( "orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "orange_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "orange_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([240, 118, 19]), + color: Color([240, 118, 19]), }, ), ( "oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([82, 162, 132]), + color: Color([82, 162, 132]), }, ), ( "oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "packed_ice", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([141, 180, 250]), + color: Color([141, 180, 250]), }, ), ( "packed_mud", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 106, 79]), + color: Color([142, 106, 79]), }, ), ( "pearlescent_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([245, 240, 239]), + color: Color([245, 240, 239]), }, ), ( "peony", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([129, 126, 139]), + color: Color([129, 126, 139]), }, ), ( "petrified_oak_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "pink_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "pink_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "pink_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "pink_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "pink_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([237, 141, 172]), + color: Color([237, 141, 172]), }, ), ( "pink_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([213, 101, 142]), + color: Color([213, 101, 142]), }, ), ( "pink_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([228, 153, 181]), + color: Color([228, 153, 181]), }, ), ( "pink_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 154, 181]), + color: Color([235, 154, 181]), }, ), ( "pink_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([230, 121, 157]), + color: Color([230, 121, 157]), }, ), ( "pink_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([242, 127, 165]), + color: Color([242, 127, 165]), }, ), ( "pink_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([233, 122, 159]), + color: Color([233, 122, 159]), }, ), ( "pink_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([161, 78, 78]), + color: Color([161, 78, 78]), }, ), ( "pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "pink_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "pink_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([237, 141, 172]), + color: Color([237, 141, 172]), }, ), ( "piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 104, 96]), + color: Color([109, 104, 96]), }, ), ( "piston_head", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([153, 127, 85]), + color: Color([153, 127, 85]), }, ), ( "player_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "player_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "podzol", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([91, 63, 24]), + color: Color([91, 63, 24]), }, ), ( "pointed_dripstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([129, 102, 89]), + color: Color([129, 102, 89]), }, ), ( "polished_andesite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([132, 134, 133]), + color: Color([132, 134, 133]), }, ), ( "polished_andesite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([132, 134, 133]), + color: Color([132, 134, 133]), }, ), ( "polished_andesite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([132, 134, 133]), + color: Color([132, 134, 133]), }, ), ( "polished_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 98, 100]), + color: Color([99, 98, 100]), }, ), ( "polished_blackstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "polished_blackstone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([48, 42, 49]), + color: Color([48, 42, 49]), }, ), ( "polished_blackstone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([48, 42, 49]), + color: Color([48, 42, 49]), }, ), ( "polished_blackstone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([48, 42, 49]), + color: Color([48, 42, 49]), }, ), ( "polished_blackstone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([48, 42, 49]), + color: Color([48, 42, 49]), }, ), ( "polished_blackstone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "polished_blackstone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "polished_blackstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "polished_blackstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "polished_blackstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 48, 56]), + color: Color([53, 48, 56]), }, ), ( "polished_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 73]), + color: Color([72, 72, 73]), }, ), ( "polished_deepslate_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 73]), + color: Color([72, 72, 73]), }, ), ( "polished_deepslate_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 73]), + color: Color([72, 72, 73]), }, ), ( "polished_deepslate_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 73]), + color: Color([72, 72, 73]), }, ), ( "polished_diorite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 193, 194]), + color: Color([192, 193, 194]), }, ), ( "polished_diorite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 193, 194]), + color: Color([192, 193, 194]), }, ), ( "polished_diorite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 193, 194]), + color: Color([192, 193, 194]), }, ), ( "polished_granite", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 106, 89]), + color: Color([154, 106, 89]), }, ), ( "polished_granite_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 106, 89]), + color: Color([154, 106, 89]), }, ), ( "polished_granite_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 106, 89]), + color: Color([154, 106, 89]), }, ), ( "poppy", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "potatoes", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([84, 135, 47]), + color: Color([84, 135, 47]), }, ), ( "potted_acacia_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([118, 117, 23]), + color: Color([118, 117, 23]), }, ), ( "potted_allium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([158, 137, 183]), + color: Color([158, 137, 183]), }, ), ( "potted_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([101, 124, 47]), + color: Color([101, 124, 47]), }, ), ( "potted_azure_bluet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([169, 204, 127]), + color: Color([169, 204, 127]), }, ), ( "potted_bamboo", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 144, 19]), + color: Color([93, 144, 19]), }, ), ( "potted_birch_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 160, 79]), + color: Color([127, 160, 79]), }, ), ( "potted_blue_orchid", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 162, 168]), + color: Color([47, 162, 168]), }, ), ( "potted_brown_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([153, 116, 92]), + color: Color([153, 116, 92]), }, ), ( "potted_cactus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([85, 127, 43]), + color: Color([85, 127, 43]), }, ), ( "potted_cornflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 121, 146]), + color: Color([79, 121, 146]), }, ), ( "potted_crimson_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([141, 44, 29]), + color: Color([141, 44, 29]), }, ), ( "potted_crimson_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 8, 41]), + color: Color([127, 8, 41]), }, ), ( "potted_dandelion", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([147, 172, 43]), + color: Color([147, 172, 43]), }, ), ( "potted_dark_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([61, 90, 30]), + color: Color([61, 90, 30]), }, ), ( "potted_dead_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([107, 78, 40]), + color: Color([107, 78, 40]), }, ), ( "potted_fern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([124, 124, 124]), + color: Color([124, 124, 124]), }, ), ( "potted_flowering_azalea_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([112, 121, 64]), + color: Color([112, 121, 64]), }, ), ( "potted_jungle_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 81, 16]), + color: Color([47, 81, 16]), }, ), ( "potted_lily_of_the_valley", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([123, 174, 95]), + color: Color([123, 174, 95]), }, ), ( "potted_mangrove_propagule", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([96, 174, 83]), + color: Color([96, 174, 83]), }, ), ( "potted_oak_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([77, 106, 40]), + color: Color([77, 106, 40]), }, ), ( "potted_orange_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 142, 30]), + color: Color([93, 142, 30]), }, ), ( "potted_oxeye_daisy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([179, 202, 143]), + color: Color([179, 202, 143]), }, ), ( "potted_pink_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 157, 78]), + color: Color([99, 157, 78]), }, ), ( "potted_poppy", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([128, 64, 37]), + color: Color([128, 64, 37]), }, ), ( "potted_red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([216, 75, 67]), + color: Color([216, 75, 67]), }, ), ( "potted_red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([89, 128, 32]), + color: Color([89, 128, 32]), }, ), ( "potted_spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 60, 36]), + color: Color([44, 60, 36]), }, ), ( "potted_warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([74, 109, 87]), + color: Color([74, 109, 87]), }, ), ( "potted_warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 136, 123]), + color: Color([20, 136, 123]), }, ), ( "potted_white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([93, 164, 71]), + color: Color([93, 164, 71]), }, ), ( "potted_wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([41, 44, 23]), + color: Color([41, 44, 23]), }, ), ( "powder_snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 253, 253]), + color: Color([248, 253, 253]), }, ), ( "powder_snow_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 72, 74]), + color: Color([73, 72, 74]), }, ), ( "powered_rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 109, 74]), + color: Color([137, 109, 74]), }, ), ( "prismarine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 156, 151]), + color: Color([99, 156, 151]), }, ), ( "prismarine_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 171, 158]), + color: Color([99, 171, 158]), }, ), ( "prismarine_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 171, 158]), + color: Color([99, 171, 158]), }, ), ( "prismarine_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 171, 158]), + color: Color([99, 171, 158]), }, ), ( "prismarine_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 156, 151]), + color: Color([99, 156, 151]), }, ), ( "prismarine_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 156, 151]), + color: Color([99, 156, 151]), }, ), ( "prismarine_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([99, 156, 151]), + color: Color([99, 156, 151]), }, ), ( "pumpkin", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([198, 118, 24]), + color: Color([198, 118, 24]), }, ), ( "pumpkin_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([154, 154, 154]), + color: Color([154, 154, 154]), }, ), ( "purple_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "purple_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "purple_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "purple_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "purple_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([121, 42, 172]), + color: Color([121, 42, 172]), }, ), ( "purple_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([100, 31, 156]), + color: Color([100, 31, 156]), }, ), ( "purple_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 55, 177]), + color: Color([131, 55, 177]), }, ), ( "purple_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 48, 152]), + color: Color([109, 48, 152]), }, ), ( "purple_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 32, 156]), + color: Color([103, 32, 156]), }, ), ( "purple_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([127, 63, 178]), + color: Color([127, 63, 178]), }, ), ( "purple_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 61, 171]), + color: Color([122, 61, 171]), }, ), ( "purple_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([118, 70, 86]), + color: Color([118, 70, 86]), }, ), ( "purple_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "purple_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([121, 42, 172]), + color: Color([121, 42, 172]), }, ), ( "purpur_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([169, 125, 169]), + color: Color([169, 125, 169]), }, ), ( "purpur_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([171, 129, 171]), + color: Color([171, 129, 171]), }, ), ( "purpur_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([169, 125, 169]), + color: Color([169, 125, 169]), }, ), ( "purpur_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([169, 125, 169]), + color: Color([169, 125, 169]), }, ), ( "quartz_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "quartz_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([234, 229, 221]), + color: Color([234, 229, 221]), }, ), ( "quartz_pillar", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 230, 224]), + color: Color([235, 230, 224]), }, ), ( "quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "rail", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 111, 88]), + color: Color([125, 111, 88]), }, ), ( "raw_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 105, 79]), + color: Color([154, 105, 79]), }, ), ( "raw_gold_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([221, 169, 46]), + color: Color([221, 169, 46]), }, ), ( "raw_iron_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([166, 135, 107]), + color: Color([166, 135, 107]), }, ), ( "red_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "red_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 39, 34]), + color: Color([160, 39, 34]), }, ), ( "red_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 32, 32]), + color: Color([142, 32, 32]), }, ), ( "red_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([168, 54, 50]), + color: Color([168, 54, 50]), }, ), ( "red_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 59, 53]), + color: Color([181, 59, 53]), }, ), ( "red_mushroom", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_mushroom_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([200, 46, 45]), + color: Color([200, 46, 45]), }, ), ( "red_nether_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([69, 7, 9]), + color: Color([69, 7, 9]), }, ), ( "red_nether_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([69, 7, 9]), + color: Color([69, 7, 9]), }, ), ( "red_nether_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([69, 7, 9]), + color: Color([69, 7, 9]), }, ), ( "red_nether_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([69, 7, 9]), + color: Color([69, 7, 9]), }, ), ( "red_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([190, 102, 33]), + color: Color([190, 102, 33]), }, ), ( "red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "red_sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "red_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([140, 31, 30]), + color: Color([140, 31, 30]), }, ), ( "red_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([153, 51, 51]), + color: Color([153, 51, 51]), }, ), ( "red_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([147, 48, 48]), + color: Color([147, 48, 48]), }, ), ( "red_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([143, 61, 46]), + color: Color([143, 61, 46]), }, ), ( "red_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "red_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 39, 34]), + color: Color([160, 39, 34]), }, ), ( "redstone_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([175, 24, 5]), + color: Color([175, 24, 5]), }, ), ( "redstone_lamp", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([95, 54, 30]), + color: Color([95, 54, 30]), }, ), ( "redstone_ore", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([140, 109, 109]), + color: Color([140, 109, 109]), }, ), ( "redstone_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "redstone_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "redstone_wire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([175, 24, 5]), + color: Color([175, 24, 5]), }, ), ( "reinforced_deepslate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 82, 78]), + color: Color([80, 82, 78]), }, ), ( "repeater", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 157, 156]), + color: Color([160, 157, 156]), }, ), ( "repeating_command_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([129, 111, 176]), + color: Color([129, 111, 176]), }, ), ( "respawn_anchor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([75, 26, 144]), + color: Color([75, 26, 144]), }, ), ( "rooted_dirt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([144, 103, 76]), + color: Color([144, 103, 76]), }, ), ( "rose_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([131, 66, 37]), + color: Color([131, 66, 37]), }, ), ( "sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([219, 207, 163]), + color: Color([219, 207, 163]), }, ), ( "sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "sandstone_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "scaffolding", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([174, 134, 80]), + color: Color([174, 134, 80]), }, ), ( "sculk", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([12, 29, 36]), + color: Color([12, 29, 36]), }, ), ( "sculk_catalyst", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([15, 31, 38]), + color: Color([15, 31, 38]), }, ), ( "sculk_sensor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([7, 70, 84]), + color: Color([7, 70, 84]), }, ), ( "sculk_shrieker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([198, 205, 169]), + color: Color([198, 205, 169]), }, ), ( "sculk_vein", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([7, 48, 57]), + color: Color([7, 48, 57]), }, ), ( "sea_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([172, 199, 190]), + color: Color([172, 199, 190]), }, ), ( "sea_pickle", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([90, 97, 39]), + color: Color([90, 97, 39]), }, ), ( "seagrass", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "shroomlight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([240, 146, 70]), + color: Color([240, 146, 70]), }, ), ( "shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([139, 96, 139]), + color: Color([139, 96, 139]), }, ), ( "sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "slime_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([111, 192, 91]), + color: Color([111, 192, 91]), }, ), ( "small_amethyst_bud", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "small_dripleaf", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "smithing_table", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([57, 58, 70]), + color: Color([57, 58, 70]), }, ), ( "smoker", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([85, 83, 81]), + color: Color([85, 83, 81]), }, ), ( "smooth_basalt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 72, 78]), + color: Color([72, 72, 78]), }, ), ( "smooth_quartz", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "smooth_quartz_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "smooth_quartz_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([235, 229, 222]), + color: Color([235, 229, 222]), }, ), ( "smooth_red_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "smooth_red_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "smooth_red_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([181, 97, 31]), + color: Color([181, 97, 31]), }, ), ( "smooth_sandstone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "smooth_sandstone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "smooth_sandstone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([223, 214, 170]), + color: Color([223, 214, 170]), }, ), ( "smooth_stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([158, 158, 158]), + color: Color([158, 158, 158]), }, ), ( "smooth_stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([158, 158, 158]), + color: Color([158, 158, 158]), }, ), ( "snow", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([249, 254, 254]), + color: Color([249, 254, 254]), }, ), ( "snow_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([249, 254, 254]), + color: Color([249, 254, 254]), }, ), ( "soul_campfire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([80, 204, 208]), + color: Color([80, 204, 208]), }, ), ( "soul_fire", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([51, 192, 197]), + color: Color([51, 192, 197]), }, ), ( "soul_lantern", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([71, 99, 114]), + color: Color([71, 99, 114]), }, ), ( "soul_sand", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([81, 62, 50]), + color: Color([81, 62, 50]), }, ), ( "soul_soil", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([75, 57, 46]), + color: Color([75, 57, 46]), }, ), ( "soul_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "soul_wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "spawner", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([36, 46, 62]), + color: Color([36, 46, 62]), }, ), ( "sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([195, 192, 74]), + color: Color([195, 192, 74]), }, ), ( "spore_blossom", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([206, 96, 158]), + color: Color([206, 96, 158]), }, ), ( "spruce_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "spruce_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([106, 80, 48]), + color: Color([106, 80, 48]), }, ), ( "spruce_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_leaves", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Spruce}), - color: BlockColor([126, 126, 126]), + color: Color([126, 126, 126]), }, ), ( "spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([108, 80, 46]), + color: Color([108, 80, 46]), }, ), ( "spruce_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_sapling", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 60, 36]), + color: Color([44, 60, 36]), }, ), ( "spruce_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([114, 84, 48]), + color: Color([114, 84, 48]), }, ), ( "spruce_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([103, 79, 47]), + color: Color([103, 79, 47]), }, ), ( "spruce_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([58, 37, 16]), + color: Color([58, 37, 16]), }, ), ( "sticky_piston", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 104, 96]), + color: Color([109, 104, 96]), }, ), ( "stone", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "stone_brick_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 121, 122]), + color: Color([122, 121, 122]), }, ), ( "stone_brick_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 121, 122]), + color: Color([122, 121, 122]), }, ), ( "stone_brick_wall", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 121, 122]), + color: Color([122, 121, 122]), }, ), ( "stone_bricks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([122, 121, 122]), + color: Color([122, 121, 122]), }, ), ( "stone_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "stone_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "stone_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "stone_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([125, 125, 125]), + color: Color([125, 125, 125]), }, ), ( "stonecutter", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([123, 118, 111]), + color: Color([123, 118, 111]), }, ), ( "stripped_acacia_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([166, 91, 51]), + color: Color([166, 91, 51]), }, ), ( "stripped_acacia_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([174, 92, 59]), + color: Color([174, 92, 59]), }, ), ( "stripped_birch_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 171, 116]), + color: Color([191, 171, 116]), }, ), ( "stripped_birch_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([196, 176, 118]), + color: Color([196, 176, 118]), }, ), ( "stripped_crimson_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([137, 57, 90]), + color: Color([137, 57, 90]), }, ), ( "stripped_crimson_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([121, 56, 82]), + color: Color([121, 56, 82]), }, ), ( "stripped_dark_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([65, 44, 22]), + color: Color([65, 44, 22]), }, ), ( "stripped_dark_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([72, 56, 36]), + color: Color([72, 56, 36]), }, ), ( "stripped_jungle_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([165, 122, 81]), + color: Color([165, 122, 81]), }, ), ( "stripped_jungle_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([171, 132, 84]), + color: Color([171, 132, 84]), }, ), ( "stripped_mangrove_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 43, 43]), + color: Color([109, 43, 43]), }, ), ( "stripped_mangrove_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([119, 54, 47]), + color: Color([119, 54, 47]), }, ), ( "stripped_oak_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([160, 129, 77]), + color: Color([160, 129, 77]), }, ), ( "stripped_oak_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([177, 144, 86]), + color: Color([177, 144, 86]), }, ), ( "stripped_spruce_log", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([105, 80, 46]), + color: Color([105, 80, 46]), }, ), ( "stripped_spruce_wood", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([115, 89, 52]), + color: Color([115, 89, 52]), }, ), ( "stripped_warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([57, 150, 147]), + color: Color([57, 150, 147]), }, ), ( "stripped_warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([52, 128, 124]), + color: Color([52, 128, 124]), }, ), ( "structure_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([88, 74, 90]), + color: Color([88, 74, 90]), }, ), ( "structure_void", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "sugar_cane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([148, 192, 101]), + color: Color([148, 192, 101]), }, ), ( "sunflower", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([246, 196, 54]), + color: Color([246, 196, 54]), }, ), ( "sweet_berry_bush", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([68, 77, 50]), + color: Color([68, 77, 50]), }, ), ( "tall_grass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([151, 149, 151]), + color: Color([151, 149, 151]), }, ), ( "tall_seagrass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([59, 139, 14]), + color: Color([59, 139, 14]), }, ), ( "target", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([226, 170, 157]), + color: Color([226, 170, 157]), }, ), ( "terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([152, 94, 67]), + color: Color([152, 94, 67]), }, ), ( "tinted_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 38, 46]), + color: Color([44, 38, 46]), }, ), ( "tnt", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([142, 62, 53]), + color: Color([142, 62, 53]), }, ), ( "torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "trapped_chest", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([162, 130, 78]), + color: Color([162, 130, 78]), }, ), ( "tripwire", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "tripwire_hook", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "tube_coral", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "tube_coral_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([49, 87, 206]), + color: Color([49, 87, 206]), }, ), ( "tube_coral_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "tube_coral_wall_fan", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "tuff", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([108, 109, 102]), + color: Color([108, 109, 102]), }, ), ( "turtle_egg", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([228, 226, 191]), + color: Color([228, 226, 191]), }, ), ( "twisting_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 143, 124]), + color: Color([20, 143, 124]), }, ), ( "twisting_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 135, 122]), + color: Color([20, 135, 122]), }, ), ( "verdant_froglight", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([229, 244, 228]), + color: Color([229, 244, 228]), }, ), ( "vine", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Grass}), - color: BlockColor([116, 116, 116]), + color: Color([116, 116, 116]), }, ), ( "void_air", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "wall_torch", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "warped_button", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "warped_door", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([44, 126, 120]), + color: Color([44, 126, 120]), }, ), ( "warped_fence", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_fence_gate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_fungus", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "warped_hyphae", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([58, 58, 77]), + color: Color([58, 58, 77]), }, ), ( "warped_nylium", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 114, 101]), + color: Color([43, 114, 101]), }, ), ( "warped_planks", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_pressure_plate", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_roots", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([20, 138, 124]), + color: Color([20, 138, 124]), }, ), ( "warped_sign", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([43, 104, 99]), + color: Color([43, 104, 99]), }, ), ( "warped_stem", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([53, 109, 110]), + color: Color([53, 109, 110]), }, ), ( "warped_trapdoor", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([47, 119, 111]), + color: Color([47, 119, 111]), }, ), ( "warped_wall_sign", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "warped_wart_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([22, 119, 121]), + color: Color([22, 119, 121]), }, ), ( "water", BlockType { flags: make_bitflags!(BlockFlag::{Opaque|Water}), - color: BlockColor([177, 177, 177]), + color: Color([177, 177, 177]), }, ), ( "water_cauldron", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([73, 72, 74]), + color: Color([73, 72, 74]), }, ), ( "waxed_copper_block", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([192, 107, 79]), + color: Color([192, 107, 79]), }, ), ( "waxed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "waxed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "waxed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([191, 106, 80]), + color: Color([191, 106, 80]), }, ), ( "waxed_exposed_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([161, 125, 103]), + color: Color([161, 125, 103]), }, ), ( "waxed_exposed_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "waxed_exposed_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "waxed_exposed_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([154, 121, 101]), + color: Color([154, 121, 101]), }, ), ( "waxed_oxidized_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([82, 162, 132]), + color: Color([82, 162, 132]), }, ), ( "waxed_oxidized_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "waxed_oxidized_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "waxed_oxidized_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([79, 153, 126]), + color: Color([79, 153, 126]), }, ), ( "waxed_weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([108, 153, 110]), + color: Color([108, 153, 110]), }, ), ( "waxed_weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "waxed_weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "waxed_weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "weathered_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([108, 153, 110]), + color: Color([108, 153, 110]), }, ), ( "weathered_cut_copper", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "weathered_cut_copper_slab", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "weathered_cut_copper_stairs", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([109, 145, 107]), + color: Color([109, 145, 107]), }, ), ( "weeping_vines", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([104, 1, 0]), + color: Color([104, 1, 0]), }, ), ( "weeping_vines_plant", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([132, 16, 12]), + color: Color([132, 16, 12]), }, ), ( "wet_sponge", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([171, 181, 70]), + color: Color([171, 181, 70]), }, ), ( "wheat", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([166, 151, 73]), + color: Color([166, 151, 73]), }, ), ( "white_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "white_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "white_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "white_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "white_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([233, 236, 236]), + color: Color([233, 236, 236]), }, ), ( "white_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([207, 213, 214]), + color: Color([207, 213, 214]), }, ), ( "white_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([225, 227, 227]), + color: Color([225, 227, 227]), }, ), ( "white_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([188, 212, 202]), + color: Color([188, 212, 202]), }, ), ( "white_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([215, 220, 221]), + color: Color([215, 220, 221]), }, ), ( "white_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([255, 255, 255]), + color: Color([255, 255, 255]), }, ), ( "white_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([246, 246, 246]), + color: Color([246, 246, 246]), }, ), ( "white_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([209, 178, 161]), + color: Color([209, 178, 161]), }, ), ( "white_tulip", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "white_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "white_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([233, 236, 236]), + color: Color([233, 236, 236]), }, ), ( "wither_rose", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "wither_skeleton_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "wither_skeleton_wall_skull", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "yellow_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "yellow_bed", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "yellow_candle", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "yellow_candle_cake", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 222, 214]), + color: Color([248, 222, 214]), }, ), ( "yellow_carpet", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 197, 39]), + color: Color([248, 197, 39]), }, ), ( "yellow_concrete", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([240, 175, 21]), + color: Color([240, 175, 21]), }, ), ( "yellow_concrete_powder", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([232, 199, 54]), + color: Color([232, 199, 54]), }, ), ( "yellow_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([234, 192, 88]), + color: Color([234, 192, 88]), }, ), ( "yellow_shulker_box", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 188, 29]), + color: Color([248, 188, 29]), }, ), ( "yellow_stained_glass", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([229, 229, 51]), + color: Color([229, 229, 51]), }, ), ( "yellow_stained_glass_pane", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([221, 221, 48]), + color: Color([221, 221, 48]), }, ), ( "yellow_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([186, 133, 35]), + color: Color([186, 133, 35]), }, ), ( "yellow_wall_banner", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "yellow_wool", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: BlockColor([248, 197, 39]), + color: Color([248, 197, 39]), }, ), ( "zombie_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ( "zombie_wall_head", BlockType { flags: make_bitflags!(BlockFlag::{}), - color: BlockColor([0, 0, 0]), + color: Color([0, 0, 0]), }, ), ]; diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 672daa0..806ba27 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -34,7 +34,7 @@ where } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct BlockColor(pub [u8; 3]); +pub struct Color(pub [u8; 3]); #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockType { @@ -43,7 +43,7 @@ pub struct BlockType { deserialize_with = "deserialize_block_flags" )] pub flags: BitFlags, - pub color: BlockColor, + pub color: Color, } impl BlockType { From 524b1b1913ef785fbb1ef9e45946b36f0e4f3dad Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 6 Apr 2023 21:35:01 +0200 Subject: [PATCH 148/460] resource: add biome data --- src/resource/biomes.rs | 372 +++++++++++++++++++++++++++++++++++++++++ src/resource/mod.rs | 53 ++++++ 2 files changed, 425 insertions(+) create mode 100644 src/resource/biomes.rs diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs new file mode 100644 index 0000000..1421883 --- /dev/null +++ b/src/resource/biomes.rs @@ -0,0 +1,372 @@ +use super::Color; + +#[derive(Debug, Clone, Copy)] +pub enum BiomeGrassColorModifier { + DarkForest, + Swamp, +} + +#[derive(Debug, Clone, Copy)] +pub struct Biome { + pub temp: i8, + pub downfall: i8, + pub water_color: Option, + pub foliage_color: Option, + pub grass_color: Option, + pub grass_color_modifier: Option, +} + +impl Biome { + const fn new(temp: i16, downfall: i16) -> Biome { + 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, + } + } + + const fn water(self, water_color: [u8; 3]) -> Biome { + Biome { + water_color: Some(Color(water_color)), + ..self + } + } + + const fn foliage(self, foliage_color: [u8; 3]) -> Biome { + Biome { + foliage_color: Some(Color(foliage_color)), + ..self + } + } + + const fn grass(self, grass_color: [u8; 3]) -> Biome { + Biome { + grass_color: Some(Color(grass_color)), + ..self + } + } + + const fn modify(self, grass_color_modifier: BiomeGrassColorModifier) -> Biome { + Biome { + grass_color_modifier: Some(grass_color_modifier), + ..self + } + } +} + +// Data extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn + +#[allow(clippy::zero_prefixed_literal)] +pub const BIOMES: &[(&str, Biome)] = { + use BiomeGrassColorModifier::*; + + &[ + // 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)), + ("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)), + ("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)), + ] +}; + +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"), +]; + +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/src/resource/mod.rs b/src/resource/mod.rs index 806ba27..62c5d9c 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -1,3 +1,4 @@ +mod biomes; mod block_types; mod legacy_block_types; @@ -87,3 +88,55 @@ impl BlockTypes { Some(self.legacy_block_types[id as usize][data as usize]) } } + +pub use biomes::Biome; + +#[derive(Debug)] +pub struct BiomeTypes { + biome_map: HashMap, + legacy_biomes: Box<[&'static Biome; 256]>, +} + +impl Default for BiomeTypes { + fn default() -> Self { + let mut biome_map: HashMap<_, _> = biomes::BIOMES + .iter() + .map(|(k, v)| (String::from(*k), v)) + .collect(); + + for &(old, new) in biomes::BIOME_ALIASES.iter().rev() { + let biome = biome_map + .get(new) + .copied() + .expect("Biome alias for unknown biome"); + assert!(biome_map.insert(String::from(old), biome).is_none()); + } + + let legacy_biomes = (0..=255) + .map(|index| { + let id = biomes::legacy_biome(index); + *biome_map.get(id).expect("Unknown legacy biome") + }) + .collect::>() + .try_into() + .unwrap(); + + Self { + biome_map, + legacy_biomes, + } + } +} + +impl BiomeTypes { + #[inline] + pub fn get(&self, id: &str) -> Option<&Biome> { + let suffix = id.strip_prefix("minecraft:")?; + self.biome_map.get(suffix).copied() + } + + #[inline] + pub fn get_legacy(&self, id: u8) -> Option<&Biome> { + Some(self.legacy_biomes[id as usize]) + } +} From e117c769375ff67317749650d513efeec6c4360b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 7 Apr 2023 09:29:01 +0200 Subject: [PATCH 149/460] world: pass biome data into chunk/section structures --- src/main.rs | 4 +++- src/world/chunk.rs | 31 ++++++++++++++++++++++--------- src/world/section.rs | 35 ++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index a0afa43..fcd588d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,6 +96,7 @@ where /// Type with methods for processing the regions of a Minecraft save directory struct RegionProcessor<'a> { block_types: resource::BlockTypes, + biome_types: resource::BiomeTypes, config: &'a Config, } @@ -103,6 +104,7 @@ impl<'a> RegionProcessor<'a> { fn new(config: &'a Config) -> Self { RegionProcessor { block_types: resource::BlockTypes::default(), + biome_types: resource::BiomeTypes::default(), config, } } @@ -128,7 +130,7 @@ impl<'a> RegionProcessor<'a> { Box, )>, > { - let chunk = world::chunk::Chunk::new(&data, &self.block_types)?; + let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; world::layer::top_layer(&chunk) } diff --git a/src/world/chunk.rs b/src/world/chunk.rs index a9a5c6b..aa6c9a7 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -6,7 +6,10 @@ use std::{ use anyhow::{bail, Context, Result}; use super::{de, section::*}; -use crate::{resource::BlockTypes, types::*}; +use crate::{ + resource::{BiomeTypes, BlockTypes}, + types::*, +}; /// Chunk data structure wrapping a [de::Chunk] for convenient access to /// block and biome data @@ -64,14 +67,20 @@ pub struct SectionIter<'a> { impl<'a> Chunk<'a> { /// Creates a new [Chunk] from a deserialized [de::Chunk] - pub fn new(data: &'a de::Chunk, block_types: &'a BlockTypes) -> Result { + pub fn new( + data: &'a de::Chunk, + block_types: &'a BlockTypes, + biome_types: &'a BiomeTypes, + ) -> Result { let data_version = data.data_version.unwrap_or_default(); match &data.chunk { de::ChunkVariants::V1_18 { sections } => { - Self::new_v1_18(data_version, sections, block_types) + Self::new_v1_18(data_version, sections, block_types, biome_types) + } + de::ChunkVariants::V0 { level } => { + Self::new_v0(data_version, level, block_types, biome_types) } - de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level, block_types), } } @@ -80,6 +89,7 @@ impl<'a> Chunk<'a> { data_version: u32, sections: &'a Vec, block_types: &'a BlockTypes, + biome_types: &'a BiomeTypes, ) -> Result { let mut section_map = BTreeMap::new(); @@ -94,10 +104,12 @@ impl<'a> Chunk<'a> { block_types, ) .with_context(|| format!("Failed to load section at Y={}", section.y))?, - BiomesV18::new(section.biomes.data.as_deref(), §ion.biomes.palette) - .with_context(|| { - format!("Failed to load section biomes at Y={}", section.y) - })?, + BiomesV18::new( + section.biomes.data.as_deref(), + §ion.biomes.palette, + biome_types, + ) + .with_context(|| format!("Failed to load section biomes at Y={}", section.y))?, BlockLight::new(section.block_light.as_deref()).with_context(|| { format!("Failed to load section block light at Y={}", section.y) })?, @@ -113,6 +125,7 @@ impl<'a> Chunk<'a> { data_version: u32, level: &'a de::LevelV0, block_types: &'a BlockTypes, + biome_types: &'a BiomeTypes, ) -> Result { let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new(); @@ -158,7 +171,7 @@ impl<'a> Chunk<'a> { } } - let biomes = BiomesV0::new(level.biomes.as_ref()); + let biomes = BiomesV0::new(level.biomes.as_ref(), biome_types); Ok( match (section_map_v1_13.is_empty(), section_map_v0.is_empty()) { diff --git a/src/world/section.rs b/src/world/section.rs index 1aa8b7f..c943e11 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -5,7 +5,7 @@ use num_integer::div_rem; use super::de; use crate::{ - resource::{BlockType, BlockTypes}, + resource::{BiomeTypes, BlockType, BlockTypes}, types::*, }; @@ -183,7 +183,11 @@ pub struct BiomesV18<'a> { impl<'a> BiomesV18<'a> { /// Constructs a new [BiomesV18] from deserialized data structures - pub fn new(biomes: Option<&'a [i64]>, palette: &'a [String]) -> Result { + pub fn new( + biomes: Option<&'a [i64]>, + palette: &'a [String], + _biome_types: &'a BiomeTypes, + ) -> Result { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; if let Some(biomes) = biomes { @@ -208,14 +212,23 @@ impl<'a> BiomesV18<'a> { /// different pre-v1.18 Minecraft versions #[derive(Debug)] pub enum BiomesV0<'a> { - IntArrayV15(&'a fastnbt::IntArray), - IntArrayV0(&'a fastnbt::IntArray), - ByteArray(&'a fastnbt::ByteArray), + IntArrayV15 { + data: &'a fastnbt::IntArray, + biome_types: &'a BiomeTypes, + }, + IntArrayV0 { + data: &'a fastnbt::IntArray, + biome_types: &'a BiomeTypes, + }, + ByteArray { + data: &'a fastnbt::ByteArray, + biome_types: &'a BiomeTypes, + }, } impl<'a> BiomesV0<'a> { /// Constructs a new [BiomesV0] from deserialized data structures - pub fn new(biomes: Option<&'a de::BiomesV0>) -> Result { + pub fn new(biomes: Option<&'a de::BiomesV0>, biome_types: &'a BiomeTypes) -> Result { const N: usize = BLOCKS_PER_CHUNK; const MAXY: usize = 256; const BN: usize = N >> 2; @@ -223,10 +236,14 @@ impl<'a> BiomesV0<'a> { Ok(match biomes { Some(de::BiomesV0::IntArray(data)) if data.len() == BN * BN * BMAXY => { - BiomesV0::IntArrayV15(data) + BiomesV0::IntArrayV15 { data, biome_types } + } + Some(de::BiomesV0::IntArray(data)) if data.len() == N * N => { + BiomesV0::IntArrayV0 { data, biome_types } + } + Some(de::BiomesV0::ByteArray(data)) if data.len() == N * N => { + BiomesV0::ByteArray { data, biome_types } } - Some(de::BiomesV0::IntArray(data)) if data.len() == N * N => BiomesV0::IntArrayV0(data), - Some(de::BiomesV0::ByteArray(data)) if data.len() == N * N => BiomesV0::ByteArray(data), _ => bail!("Invalid biome data"), }) } From b8b0e0627f0726039134a5cf1ad9edeb771b3ee1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 7 Apr 2023 09:37:02 +0200 Subject: [PATCH 150/460] world: correctly name BiomesV1_18 --- src/world/chunk.rs | 6 +++--- src/world/section.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index aa6c9a7..026276a 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -17,7 +17,7 @@ use crate::{ pub enum Chunk<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { - section_map: BTreeMap, BiomesV18<'a>, BlockLight<'a>)>, + section_map: BTreeMap, BiomesV1_18<'a>, BlockLight<'a>)>, }, /// Minecraft v1.13+ chunk /// @@ -45,7 +45,7 @@ pub enum Chunk<'a> { enum SectionIterInner<'a> { /// Iterator over sections of [Chunk::V1_18] V1_18 { - iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV18<'a>, BlockLight<'a>)>, + iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BiomesV1_18<'a>, BlockLight<'a>)>, }, /// Iterator over sections of [Chunk::V1_13] V1_13 { @@ -104,7 +104,7 @@ impl<'a> Chunk<'a> { block_types, ) .with_context(|| format!("Failed to load section at Y={}", section.y))?, - BiomesV18::new( + BiomesV1_18::new( section.biomes.data.as_deref(), §ion.biomes.palette, biome_types, diff --git a/src/world/section.rs b/src/world/section.rs index c943e11..f960d16 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -175,13 +175,13 @@ impl<'a> Section for SectionV0<'a> { /// the biomes laid out as an array of indices into a palette, similar to the /// v1.13+ block data. #[derive(Debug)] -pub struct BiomesV18<'a> { +pub struct BiomesV1_18<'a> { _biomes: Option<&'a [i64]>, _palette: &'a [String], _bits: u8, } -impl<'a> BiomesV18<'a> { +impl<'a> BiomesV1_18<'a> { /// Constructs a new [BiomesV18] from deserialized data structures pub fn new( biomes: Option<&'a [i64]>, @@ -198,7 +198,7 @@ impl<'a> BiomesV18<'a> { } } - Ok(BiomesV18 { + Ok(BiomesV1_18 { _biomes: biomes, _palette: palette, _bits: bits, From c6843cfb9c0af41fa93fe5168f4cce33a28d2dcf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 7 Apr 2023 09:38:31 +0200 Subject: [PATCH 151/460] world: resolve biome palette entries for v1.18 biome data --- src/world/section.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index f960d16..5d2781a 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -5,7 +5,7 @@ use num_integer::div_rem; use super::de; use crate::{ - resource::{BiomeTypes, BlockType, BlockTypes}, + resource::{Biome, BiomeTypes, BlockType, BlockTypes}, types::*, }; @@ -177,7 +177,7 @@ impl<'a> Section for SectionV0<'a> { #[derive(Debug)] pub struct BiomesV1_18<'a> { _biomes: Option<&'a [i64]>, - _palette: &'a [String], + _palette: Vec>, _bits: u8, } @@ -186,7 +186,7 @@ impl<'a> BiomesV1_18<'a> { pub fn new( biomes: Option<&'a [i64]>, palette: &'a [String], - _biome_types: &'a BiomeTypes, + biome_types: &'a BiomeTypes, ) -> Result { let bits = palette_bits(palette.len(), 1, 6).context("Unsupported block palette size")?; @@ -198,9 +198,20 @@ impl<'a> BiomesV1_18<'a> { } } + let palette_types = palette + .iter() + .map(|entry| { + let biome_type = biome_types.get(entry); + if biome_type.is_none() { + eprintln!("Unknown biome type: {}", entry); + } + biome_type + }) + .collect(); + Ok(BiomesV1_18 { _biomes: biomes, - _palette: palette, + _palette: palette_types, _bits: bits, }) } From 3ea93296d7f54f770888260f1b0693d21b95bfdd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 8 Apr 2023 21:19:55 +0200 Subject: [PATCH 152/460] Update dependencies --- Cargo.lock | 155 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4ca24e2..5a3f9e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -141,7 +141,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.12", + "syn", ] [[package]] @@ -177,7 +177,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" dependencies = [ - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -197,33 +197,33 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "enumflags2" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +checksum = "0044ebdf7fbb2a772e0c0233a9d3173c5cd8af8ae7078d4c5188af44ffffaa4b" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +checksum = "9d2c772ccdbdfd1967b4f5d79d17c98ebf92009fdcc838db7aa434462f600c26" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "errno" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -287,25 +287,25 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -328,9 +328,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libz-ng-sys" @@ -431,9 +431,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.54" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -449,16 +449,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.6" +version = "0.37.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -487,7 +487,7 @@ checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn", ] [[package]] @@ -498,20 +498,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", @@ -536,7 +525,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[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.0", ] [[package]] @@ -545,13 +543,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -560,42 +573,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "zstd" version = "0.12.3+zstd.1.5.2" @@ -607,9 +662,9 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "6.0.4+zstd.1.5.4" +version = "6.0.5+zstd.1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" dependencies = [ "libc", "zstd-sys", @@ -617,9 +672,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.7+zstd.1.5.4" +version = "2.0.8+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" dependencies = [ "cc", "libc", From aa2edc3d13919b5be48e2bde69b936857586ab53 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 8 Apr 2023 10:48:00 +0200 Subject: [PATCH 153/460] world/section: move biome_types field out of BiomesV0 enum --- src/world/section.rs | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index 5d2781a..e11f40a 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -217,24 +217,22 @@ impl<'a> BiomesV1_18<'a> { } } -/// Pre-v1.18 section biome data +/// Pre-v1.18 section biome data variants /// /// There are a 3 formats for biome data that were used in /// different pre-v1.18 Minecraft versions #[derive(Debug)] -pub enum BiomesV0<'a> { - IntArrayV15 { - data: &'a fastnbt::IntArray, - biome_types: &'a BiomeTypes, - }, - IntArrayV0 { - data: &'a fastnbt::IntArray, - biome_types: &'a BiomeTypes, - }, - ByteArray { - data: &'a fastnbt::ByteArray, - biome_types: &'a BiomeTypes, - }, +enum BiomesV0Data<'a> { + IntArrayV15(&'a fastnbt::IntArray), + IntArrayV0(&'a fastnbt::IntArray), + ByteArray(&'a fastnbt::ByteArray), +} + +/// Pre-v1.18 section biome data +#[derive(Debug)] +pub struct BiomesV0<'a> { + data: BiomesV0Data<'a>, + biome_types: &'a BiomeTypes, } impl<'a> BiomesV0<'a> { @@ -245,18 +243,19 @@ impl<'a> BiomesV0<'a> { const BN: usize = N >> 2; const BMAXY: usize = MAXY >> 2; - Ok(match biomes { + let data = match biomes { Some(de::BiomesV0::IntArray(data)) if data.len() == BN * BN * BMAXY => { - BiomesV0::IntArrayV15 { data, biome_types } + BiomesV0Data::IntArrayV15(data) } Some(de::BiomesV0::IntArray(data)) if data.len() == N * N => { - BiomesV0::IntArrayV0 { data, biome_types } + BiomesV0Data::IntArrayV0(data) } Some(de::BiomesV0::ByteArray(data)) if data.len() == N * N => { - BiomesV0::ByteArray { data, biome_types } + BiomesV0Data::ByteArray(data) } _ => bail!("Invalid biome data"), - }) + }; + Ok(BiomesV0 { data, biome_types }) } } From b93e61315275706e69140ffa59e329962f83470f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 8 Apr 2023 10:59:20 +0200 Subject: [PATCH 154/460] types: add LayerBlockCoords::offset() helper --- src/types.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/types.rs b/src/types.rs index 2598485..06e01f9 100644 --- a/src/types.rs +++ b/src/types.rs @@ -53,6 +53,20 @@ impl Debug for LayerBlockCoords { } } +impl LayerBlockCoords { + /// Computes a block's offset in various data structures + /// + /// Many chunk data structures store block and biome data in the same + /// order. This method computes the offset at which the data for the + /// block at a given coordinate is stored. + pub fn offset(&self) -> usize { + use BLOCKS_PER_CHUNK as N; + let x = self.x.0 as usize; + let z = self.z.0 as usize; + N * z + x + } +} + /// Generic array for data stored per block of a chunk layer /// /// Includes various convenient iteration functions. @@ -102,10 +116,8 @@ impl SectionBlockCoords { /// block at a given coordinate is stored. pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; - let x = self.xz.x.0 as usize; let y = self.y.0 as usize; - let z = self.xz.z.0 as usize; - ((y * N) + z) * N + x + N * N * y + self.xz.offset() } } From ddc515a9d77122264a0ca8d8a9b19df6ab33515f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 8 Apr 2023 12:10:54 +0200 Subject: [PATCH 155/460] world/section: implement biome_at() --- src/world/section.rs | 80 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/world/section.rs b/src/world/section.rs index e11f40a..5f6553d 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -169,6 +169,11 @@ impl<'a> Section for SectionV0<'a> { } } +/// Trait for common functions of [BiomesV1_18] and [BiomesV0] +pub trait Biomes: Debug { + fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result>; +} + /// Minecraft v1.18+ section biome data /// /// The biome data is part of the section structure in Minecraft v1.18+, with @@ -176,9 +181,9 @@ impl<'a> Section for SectionV0<'a> { /// v1.13+ block data. #[derive(Debug)] pub struct BiomesV1_18<'a> { - _biomes: Option<&'a [i64]>, - _palette: Vec>, - _bits: u8, + biomes: Option<&'a [i64]>, + palette: Vec>, + bits: u8, } impl<'a> BiomesV1_18<'a> { @@ -210,11 +215,45 @@ impl<'a> BiomesV1_18<'a> { .collect(); Ok(BiomesV1_18 { - _biomes: biomes, - _palette: palette_types, - _bits: bits, + biomes, + palette: palette_types, + bits, }) } + + /// Looks up the block type palette index at the given coordinates + fn palette_index_at(&self, coords: SectionBlockCoords) -> usize { + const N: usize = BLOCKS_PER_CHUNK; + const BN: usize = N >> 2; + + let Some(biomes) = self.biomes else { + return 0; + }; + + let bits = self.bits as usize; + let mask = (1 << bits) - 1; + + let x = (coords.xz.x.0 >> 2) as usize; + let y = (coords.y.0 >> 2) as usize; + let z = (coords.xz.z.0 >> 2) as usize; + let offset = BN * BN * y + BN * z + x; + + let blocks_per_word = 64 / bits; + let (word, shift) = div_rem(offset, blocks_per_word); + let shifted = biomes[word] as u64 >> (shift * bits); + + (shifted & mask) as usize + } +} + +impl<'a> Biomes for BiomesV1_18<'a> { + fn biome_at(&self, _section: SectionY, coords: SectionBlockCoords) -> Result> { + let index = self.palette_index_at(coords); + Ok(*self + .palette + .get(index) + .context("Palette index out of bounds")?) + } } /// Pre-v1.18 section biome data variants @@ -259,6 +298,35 @@ impl<'a> BiomesV0<'a> { } } +impl<'a> Biomes for BiomesV0<'a> { + fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result> { + let id = match self.data { + BiomesV0Data::IntArrayV15(data) => { + const N: usize = BLOCKS_PER_CHUNK; + const MAXY: usize = 256; + const BN: usize = N >> 2; + + let LayerBlockCoords { x, z } = coords.xz; + let y = section + .0 + .checked_mul(BLOCKS_PER_CHUNK as i32) + .and_then(|y| y.checked_add_unsigned(coords.y.0.into())) + .filter(|&height| height >= 0 && (height as usize) < MAXY) + .context("Y coordinate out of range")? as usize; + let offset = (y >> 2) * BN * BN + (z.0 >> 2) as usize * BN + (x.0 >> 2) as usize; + let id = data[offset] as u32; + id.try_into().context("Biome index out of range")? + } + BiomesV0Data::IntArrayV0(data) => { + let id = data[coords.xz.offset()] as u32; + id.try_into().context("Biome index out of range")? + } + BiomesV0Data::ByteArray(data) => data[coords.xz.offset()] as u8, + }; + Ok(self.biome_types.get_legacy(id)) + } +} + #[derive(Debug, Clone, Copy)] pub struct BlockLight<'a>(Option<&'a [i8]>); From 0d2c99dacfffc8b6d8e88db09090d3421ac12f2e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 8 Apr 2023 21:03:50 +0200 Subject: [PATCH 156/460] world/chunk: include biomes in section iterator item --- src/world/chunk.rs | 60 +++++++++++++++++++++++++++------------------- src/world/layer.rs | 1 + 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 026276a..4f743fc 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -50,10 +50,12 @@ enum SectionIterInner<'a> { /// Iterator over sections of [Chunk::V1_13] V1_13 { iter: btree_map::Iter<'a, SectionY, (SectionV1_13<'a>, BlockLight<'a>)>, + biomes: &'a BiomesV0<'a>, }, /// Iterator over sections of [Chunk::V0] V0 { iter: btree_map::Iter<'a, SectionY, (SectionV0<'a>, BlockLight<'a>)>, + biomes: &'a BiomesV0<'a>, }, /// Empty iterator over an unpopulated chunk ([Chunk::Empty]) Empty, @@ -208,11 +210,19 @@ impl<'a> Chunk<'a> { Chunk::V1_18 { section_map } => V1_18 { iter: section_map.iter(), }, - Chunk::V1_13 { section_map, .. } => V1_13 { + Chunk::V1_13 { + section_map, + biomes, + } => V1_13 { iter: section_map.iter(), + biomes, }, - Chunk::V0 { section_map, .. } => V0 { + Chunk::V0 { + section_map, + biomes, + } => V0 { iter: section_map.iter(), + biomes, }, Chunk::Empty => Empty, }, @@ -224,6 +234,7 @@ impl<'a> Chunk<'a> { pub struct SectionIterItem<'a> { pub y: SectionY, pub section: &'a dyn Section, + pub biomes: &'a dyn Biomes, pub block_light: BlockLight<'a>, } @@ -247,30 +258,29 @@ impl<'a> SectionIter<'a> { { match &mut self.inner { SectionIterInner::V1_18 { iter } => f(&mut iter.map( - |(&y, (section, _, block_light))| SectionIterItem { + |(&y, (section, biomes, block_light))| SectionIterItem { y, section, + biomes, + block_light: *block_light, + }, + )), + SectionIterInner::V1_13 { iter, biomes } => f(&mut iter.map( + |(&y, (section, block_light))| SectionIterItem { + y, + section, + biomes: *biomes, + block_light: *block_light, + }, + )), + SectionIterInner::V0 { iter, biomes } => f(&mut iter.map( + |(&y, (section, block_light))| SectionIterItem { + y, + section, + biomes: *biomes, block_light: *block_light, }, )), - SectionIterInner::V1_13 { iter } => { - f( - &mut iter.map(|(&y, (section, block_light))| SectionIterItem { - y, - section, - block_light: *block_light, - }), - ) - } - SectionIterInner::V0 { iter } => { - f( - &mut iter.map(|(&y, (section, block_light))| SectionIterItem { - y, - section, - block_light: *block_light, - }), - ) - } SectionIterInner::Empty => f(&mut iter::empty()), } } @@ -286,8 +296,8 @@ impl<'a> Iterator for SectionIter<'a> { fn size_hint(&self) -> (usize, Option) { match &self.inner { SectionIterInner::V1_18 { iter } => iter.size_hint(), - SectionIterInner::V1_13 { iter } => iter.size_hint(), - SectionIterInner::V0 { iter } => iter.size_hint(), + SectionIterInner::V1_13 { iter, .. } => iter.size_hint(), + SectionIterInner::V0 { iter, .. } => iter.size_hint(), SectionIterInner::Empty => (0, Some(0)), } } @@ -307,8 +317,8 @@ impl<'a> ExactSizeIterator for SectionIter<'a> { fn len(&self) -> usize { match &self.inner { SectionIterInner::V1_18 { iter } => iter.len(), - SectionIterInner::V1_13 { iter } => iter.len(), - SectionIterInner::V0 { iter } => iter.len(), + SectionIterInner::V1_13 { iter, .. } => iter.len(), + SectionIterInner::V0 { iter, .. } => iter.len(), SectionIterInner::Empty => 0, } } diff --git a/src/world/layer.rs b/src/world/layer.rs index fd24790..1e5abba 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -106,6 +106,7 @@ pub fn top_layer(chunk: &Chunk) -> Result, Box Date: Sun, 9 Apr 2023 22:56:02 +0200 Subject: [PATCH 157/460] world/layer: add biome data to returned layer --- src/main.rs | 7 +++++-- src/world/layer.rs | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index fcd588d..50884e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -126,7 +126,10 @@ impl<'a> RegionProcessor<'a> { data: world::de::Chunk, ) -> Result< Option<( - Box, + ( + Box, + Box, + ), Box, )>, > { @@ -192,7 +195,7 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some((processed_chunk, block_light)) = self + let Some(((processed_chunk, _), block_light)) = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { diff --git a/src/world/layer.rs b/src/world/layer.rs index 1e5abba..a457191 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use super::chunk::{Chunk, SectionIterItem}; use crate::{ - resource::{BlockFlag, BlockType}, + resource::{Biome, BlockFlag, BlockType}, types::*, }; @@ -83,6 +83,7 @@ impl OptionBlockInfoExt for Option { } pub type BlockInfoArray = LayerBlockArray>; +pub type BiomeArray = LayerBlockArray>; pub type BlockLightArray = LayerBlockArray; /// Fills in a [BlockInfoArray] with the information of the chunk's top @@ -92,7 +93,9 @@ pub type BlockLightArray = LayerBlockArray; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk) -> Result, Box)>> { +pub fn top_layer( + chunk: &Chunk, +) -> Result, Box), Box)>> { use BLOCKS_PER_CHUNK as N; if chunk.is_empty() { @@ -101,12 +104,13 @@ pub fn top_layer(chunk: &Chunk) -> Result, Box::default(); + let mut block_biomes = Box::::default(); let mut light = Box::::default(); for SectionIterItem { y: section_y, section, - biomes: _, + biomes, block_light, } in chunk.sections().rev() { @@ -133,6 +137,11 @@ pub fn top_layer(chunk: &Chunk) -> Result, Box Result, Box Date: Sun, 9 Apr 2023 23:20:20 +0200 Subject: [PATCH 158/460] main: store biome data in processed data files --- src/main.rs | 18 ++++++++++++------ src/resource/biomes.rs | 6 ++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 50884e3..e2121e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,12 @@ struct Args { } type RegionCoords = (i32, i32); -type ProcessedRegion = ChunkArray>>; +type ProcessedRegion = ChunkArray< + Option<( + Box, + Box, + )>, +>; struct Config { region_dir: PathBuf, @@ -195,7 +200,7 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some(((processed_chunk, _), block_light)) = self + let Some((processed_chunk, block_light)) = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { @@ -299,13 +304,14 @@ impl<'a> TileRenderer<'a> { fn render_chunk( image: &mut image::RgbaImage, coords: ChunkCoords, - chunk: &world::layer::BlockInfoArray, + blocks: &world::layer::BlockInfoArray, + _biomes: &world::layer::BiomeArray, ) { const N: u32 = BLOCKS_PER_CHUNK as u32; let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { image::Rgba( - match &chunk[LayerBlockCoords { + match &blocks[LayerBlockCoords { x: BlockX(x as u8), z: BlockZ(z as u8), }] { @@ -319,11 +325,11 @@ impl<'a> TileRenderer<'a> { fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { for (coords, chunk) in region.iter() { - let Some(chunk) = chunk else { + let Some((blocks, biomes)) = chunk else { continue; }; - Self::render_chunk(image, coords, chunk); + Self::render_chunk(image, coords, blocks, biomes); } } diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs index 1421883..036cafc 100644 --- a/src/resource/biomes.rs +++ b/src/resource/biomes.rs @@ -1,12 +1,14 @@ +use serde::{Deserialize, Serialize}; + use super::Color; -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum BiomeGrassColorModifier { DarkForest, Swamp, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct Biome { pub temp: i8, pub downfall: i8, From d79377ad6b36d5709ebb343cb44f1d0756697fb5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 10 Apr 2023 20:58:07 +0200 Subject: [PATCH 159/460] main: pass biome into block_color() No biome edge smoothing yet. --- src/main.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index e2121e6..223e694 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use clap::Parser; use minedmap::{ io::storage, - resource, + resource::{self, Biome}, types::*, world::{ self, @@ -288,7 +288,7 @@ impl<'a> TileRenderer<'a> { storage::read(&processed_path).context("Failed to load processed region data") } - fn block_color(block: &BlockInfo) -> [u8; 4] { + fn block_color(block: &BlockInfo, _biome: &Biome) -> [u8; 4] { let h = block .depth .map(|depth| 0.5 + 0.005 * depth.0 as f32) @@ -305,20 +305,19 @@ impl<'a> TileRenderer<'a> { image: &mut image::RgbaImage, coords: ChunkCoords, blocks: &world::layer::BlockInfoArray, - _biomes: &world::layer::BiomeArray, + biomes: &world::layer::BiomeArray, ) { const N: u32 = BLOCKS_PER_CHUNK as u32; let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { - image::Rgba( - match &blocks[LayerBlockCoords { - x: BlockX(x as u8), - z: BlockZ(z as u8), - }] { - Some(block) => Self::block_color(block), - None => [0, 0, 0, 0], - }, - ) + let coords = LayerBlockCoords { + x: BlockX(x as u8), + z: BlockZ(z as u8), + }; + image::Rgba(match (&blocks[coords], &biomes[coords]) { + (Some(block), Some(biome)) => Self::block_color(block, biome), + _ => [0, 0, 0, 0], + }) }); overlay_chunk(image, &chunk_image, coords); } From 2e05998b48396c12613f4de66949f6c7a4bf4a91 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Apr 2023 08:22:59 +0200 Subject: [PATCH 160/460] Update depenencies --- Cargo.lock | 219 +++++++++++++++++++++-------------------------------- 1 file changed, 85 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a3f9e8..7531593 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,49 +10,58 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] [[package]] -name = "anstyle-wincon" -version = "0.2.0" +name = "anstyle-query" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "autocfg" @@ -110,9 +119,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.1" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" +checksum = "8a1f23fa97e1d1641371b51f35535cb26959b8e27ab50d167a8b996b5bada819" dependencies = [ "clap_builder", "clap_derive", @@ -121,9 +130,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.1" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +checksum = "0fdc5d93c358224b4d6867ef1356d740de2303e9892edc06c5340daeccd96bab" dependencies = [ "anstream", "anstyle", @@ -166,19 +175,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" - -[[package]] -name = "concolor-query" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys 0.45.0", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "crc32fast" @@ -197,18 +197,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "enumflags2" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0044ebdf7fbb2a772e0c0233a9d3173c5cd8af8ae7078d4c5188af44ffffaa4b" +checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2c772ccdbdfd1967b4f5d79d17c98ebf92009fdcc838db7aa434462f600c26" +checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", @@ -223,7 +223,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -238,9 +238,9 @@ dependencies = [ [[package]] name = "fastnbt" -version = "2.4.3" +version = "2.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1aab2b0109236f6c89cc81b9e2ef4aced6d585aabe96ac860ee5e9a102eb198" +checksum = "3369bd70629bccfda7e344883c9ae3ab7f3b10a357bcf8b0f69caa7256bcf188" dependencies = [ "byteorder", "cesu8", @@ -249,10 +249,19 @@ dependencies = [ ] [[package]] -name = "flate2" -version = "1.0.25" +name = "fdeflate" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "libz-ng-sys", @@ -293,7 +302,7 @@ checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -305,7 +314,7 @@ dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -328,15 +337,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libz-ng-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4399ae96a9966bf581e726de86969f803a81b7ce795fcd5480e640589457e0f2" +checksum = "2468756f34903b582fe7154dc1ffdebd89d0562c4a43b53c621bb0f1b1043ccb" dependencies = [ "cmake", "libc", @@ -344,9 +353,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" [[package]] name = "minedmap" @@ -368,11 +377,12 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -419,12 +429,13 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "png" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" dependencies = [ "bitflags", "crc32fast", + "fdeflate", "flate2", "miniz_oxide", ] @@ -449,23 +460,23 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "serde" -version = "1.0.159" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] @@ -481,15 +492,21 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "simd-adler32" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" + [[package]] name = "strsim" version = "0.10.0" @@ -498,9 +515,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.13" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -519,37 +536,13 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[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.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -558,93 +551,51 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" From 61fb23b94b959f2e86a3dcbada9d9dd72219793c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Apr 2023 10:46:56 +0200 Subject: [PATCH 161/460] Move main source file to bin subdirectory --- src/{ => bin/minedmap}/main.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{ => bin/minedmap}/main.rs (100%) diff --git a/src/main.rs b/src/bin/minedmap/main.rs similarity index 100% rename from src/main.rs rename to src/bin/minedmap/main.rs From 1a5e8894fe2619083e503b63c7497983a8038783 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Apr 2023 11:01:15 +0200 Subject: [PATCH 162/460] minedmap: split up main module --- src/bin/minedmap/common.rs | 77 ++++++ src/bin/minedmap/main.rs | 385 +-------------------------- src/bin/minedmap/region_processor.rs | 183 +++++++++++++ src/bin/minedmap/tile_renderer.rs | 113 ++++++++ 4 files changed, 385 insertions(+), 373 deletions(-) create mode 100644 src/bin/minedmap/common.rs create mode 100644 src/bin/minedmap/region_processor.rs create mode 100644 src/bin/minedmap/tile_renderer.rs diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs new file mode 100644 index 0000000..ae645d1 --- /dev/null +++ b/src/bin/minedmap/common.rs @@ -0,0 +1,77 @@ +use std::path::{Path, PathBuf}; + +use minedmap::{types::*, world}; + +pub type RegionCoords = (i32, i32); +pub type ProcessedRegion = ChunkArray< + Option<( + Box, + Box, + )>, +>; + +pub struct Config { + pub region_dir: PathBuf, + pub processed_dir: PathBuf, + pub light_dir: PathBuf, + pub map_dir: PathBuf, +} + +impl Config { + pub fn new(args: super::Args) -> Self { + let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); + let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + let light_dir = [&args.output_dir, Path::new("light/0")].iter().collect(); + let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); + + Config { + region_dir, + processed_dir, + light_dir, + map_dir, + } + } + + pub fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.bin{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.processed_dir, Path::new(&filename)].iter().collect() + } + + pub fn light_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.png{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.light_dir, Path::new(&filename)].iter().collect() + } + + pub fn map_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { + let filename = format!( + "r.{}.{}.png{}", + coords.0, + coords.1, + if temp { ".tmp" } else { "" }, + ); + [&self.map_dir, Path::new(&filename)].iter().collect() + } +} + +pub fn overlay_chunk(image: &mut I, chunk: &J, coords: ChunkCoords) +where + I: image::GenericImage, + J: image::GenericImageView, +{ + image::imageops::overlay( + image, + chunk, + coords.x.0 as i64 * BLOCKS_PER_CHUNK as i64, + coords.z.0 as i64 * BLOCKS_PER_CHUNK as i64, + ); +} diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 223e694..d0714ef 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -1,383 +1,22 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; +mod common; +mod region_processor; +mod tile_renderer; -use anyhow::{Context, Result}; +use std::path::PathBuf; + +use anyhow::Result; use clap::Parser; -use minedmap::{ - io::storage, - resource::{self, Biome}, - types::*, - world::{ - self, - layer::{BlockInfo, BlockLightArray}, - }, -}; +use common::Config; +use region_processor::RegionProcessor; +use tile_renderer::TileRenderer; #[derive(Debug, Parser)] -struct Args { +pub struct Args { /// Minecraft save directory - input_dir: PathBuf, + pub input_dir: PathBuf, /// MinedMap data directory - output_dir: PathBuf, -} - -type RegionCoords = (i32, i32); -type ProcessedRegion = ChunkArray< - Option<( - Box, - Box, - )>, ->; - -struct Config { - region_dir: PathBuf, - processed_dir: PathBuf, - light_dir: PathBuf, - map_dir: PathBuf, -} - -impl Config { - fn new(args: Args) -> Self { - let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); - let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); - let light_dir = [&args.output_dir, Path::new("light/0")].iter().collect(); - let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); - - Config { - region_dir, - processed_dir, - light_dir, - map_dir, - } - } - - fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.bin{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); - [&self.processed_dir, Path::new(&filename)].iter().collect() - } - - fn light_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.png{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); - [&self.light_dir, Path::new(&filename)].iter().collect() - } - - fn map_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.png{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); - [&self.map_dir, Path::new(&filename)].iter().collect() - } -} - -fn overlay_chunk(image: &mut I, chunk: &J, coords: ChunkCoords) -where - I: image::GenericImage, - J: image::GenericImageView, -{ - image::imageops::overlay( - image, - chunk, - coords.x.0 as i64 * BLOCKS_PER_CHUNK as i64, - coords.z.0 as i64 * BLOCKS_PER_CHUNK as i64, - ); -} - -/// Type with methods for processing the regions of a Minecraft save directory -struct RegionProcessor<'a> { - block_types: resource::BlockTypes, - biome_types: resource::BiomeTypes, - config: &'a Config, -} - -impl<'a> RegionProcessor<'a> { - fn new(config: &'a Config) -> Self { - RegionProcessor { - block_types: resource::BlockTypes::default(), - biome_types: resource::BiomeTypes::default(), - config, - } - } - - /// Parses a filename in the format r.X.Z.mca into the contained X and Z values - fn parse_region_filename(path: &Path) -> Option { - let file_name = path.file_name()?.to_str()?; - let parts: Vec<_> = file_name.split('.').collect(); - let &["r", x, z, "mca"] = parts.as_slice() else { - return None; - }; - - Some((x.parse().ok()?, z.parse().ok()?)) - } - - /// Processes a single chunk - fn process_chunk( - &self, - data: world::de::Chunk, - ) -> Result< - Option<( - ( - Box, - Box, - ), - Box, - )>, - > { - let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; - world::layer::top_layer(&chunk) - } - - fn chunk_lightmap(block_light: Box) -> image::GrayAlphaImage { - const N: u32 = BLOCKS_PER_CHUNK as u32; - - image::GrayAlphaImage::from_fn(N, N, |x, z| { - let v: f32 = block_light[LayerBlockCoords { - x: BlockX(x as u8), - z: BlockZ(z as u8), - }] - .into(); - image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) - }) - } - - fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { - let tmp_path = self.config.processed_path(coords, true); - storage::write(&tmp_path, processed_region)?; - - let output_path = self.config.processed_path(coords, false); - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - - Ok(()) - } - - fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { - let tmp_path = self.config.light_path(coords, true); - lightmap - .save_with_format(&tmp_path, image::ImageFormat::Png) - .context("Failed to save image")?; - - let output_path = self.config.light_path(coords, false); - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - - Ok(()) - } - - /// Processes a single region file - fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - - println!("Processing region r.{}.{}.mca", coords.0, coords.1); - - let mut processed_region = ProcessedRegion::default(); - let mut lightmap = image::GrayAlphaImage::new(N, N); - - minedmap::io::region::from_file(path)?.foreach_chunk( - |chunk_coords, data: world::de::Chunk| { - let Some((processed_chunk, block_light)) = self - .process_chunk(data) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? - else { - return Ok(()); - }; - processed_region[chunk_coords] = Some(processed_chunk); - - let chunk_lightmap = Self::chunk_lightmap(block_light); - overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); - - Ok(()) - }, - )?; - - self.save_region(coords, &processed_region)?; - self.save_lightmap(coords, &lightmap)?; - - Ok(()) - } - - /// Iterates over all region files of a Minecraft save directory - /// - /// Returns a list of the coordinates of all processed regions - fn run(self) -> Result> { - let read_dir = self.config.region_dir.read_dir().with_context(|| { - format!( - "Failed to read directory {}", - self.config.region_dir.display() - ) - })?; - - fs::create_dir_all(&self.config.processed_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.processed_dir.display(), - ) - })?; - fs::create_dir_all(&self.config.light_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.light_dir.display(), - ) - })?; - - let mut ret = Vec::new(); - - for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { - // We are only interested in regular files - entry - .file_type() - .map(|file_type| file_type.is_file()) - .unwrap_or_default() - }) { - let path = entry.path(); - let Some(coords) = Self::parse_region_filename(&path) else { - continue; - }; - - if let Err(err) = self.process_region(&path, coords) { - eprintln!( - "Failed to process region {}: {:?}", - path.file_name().unwrap_or_default().to_string_lossy(), - err, - ); - } - - ret.push(coords); - } - - Ok(ret) - } -} - -struct TileRenderer<'a> { - config: &'a Config, -} - -impl<'a> TileRenderer<'a> { - fn new(config: &'a Config) -> Self { - TileRenderer { config } - } - - fn load_region(&self, coords: RegionCoords) -> Result { - let processed_path = self.config.processed_path(coords, false); - storage::read(&processed_path).context("Failed to load processed region data") - } - - fn block_color(block: &BlockInfo, _biome: &Biome) -> [u8; 4] { - let h = block - .depth - .map(|depth| 0.5 + 0.005 * depth.0 as f32) - .unwrap_or_default(); - let c = block - .block_type - .color - .0 - .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); - [c[0], c[1], c[2], 255] - } - - fn render_chunk( - image: &mut image::RgbaImage, - coords: ChunkCoords, - blocks: &world::layer::BlockInfoArray, - biomes: &world::layer::BiomeArray, - ) { - const N: u32 = BLOCKS_PER_CHUNK as u32; - - let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { - let coords = LayerBlockCoords { - x: BlockX(x as u8), - z: BlockZ(z as u8), - }; - image::Rgba(match (&blocks[coords], &biomes[coords]) { - (Some(block), Some(biome)) => Self::block_color(block, biome), - _ => [0, 0, 0, 0], - }) - }); - overlay_chunk(image, &chunk_image, coords); - } - - fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { - for (coords, chunk) in region.iter() { - let Some((blocks, biomes)) = chunk else { - continue; - }; - - Self::render_chunk(image, coords, blocks, biomes); - } - } - - fn render_tile(&self, coords: RegionCoords) -> Result<()> { - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - - let tmp_path = self.config.map_path(coords, true); - let output_path = self.config.map_path(coords, false); - println!( - "Rendering tile {}", - output_path - .file_name() - .unwrap_or_default() - .to_string_lossy(), - ); - - let region = self.load_region(coords)?; - let mut image = image::RgbaImage::new(N, N); - Self::render_region(&mut image, ®ion); - image - .save_with_format(&tmp_path, image::ImageFormat::Png) - .context("Failed to save image")?; - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - - Ok(()) - } - - fn run(self, regions: &[RegionCoords]) -> Result<()> { - fs::create_dir_all(&self.config.map_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.map_dir.display(), - ) - })?; - - for &coords in regions { - if let Err(err) = self.render_tile(coords) { - eprintln!("Failed to render tile {:?}: {:?}", coords, err,); - } - } - - Ok(()) - } + pub output_dir: PathBuf, } fn main() -> Result<()> { diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs new file mode 100644 index 0000000..640467c --- /dev/null +++ b/src/bin/minedmap/region_processor.rs @@ -0,0 +1,183 @@ +use std::{fs, path::Path}; + +use anyhow::{Context, Result}; + +use minedmap::{io::storage, resource, types::*, world}; + +use super::common::*; + +/// Type with methods for processing the regions of a Minecraft save directory +pub struct RegionProcessor<'a> { + block_types: resource::BlockTypes, + biome_types: resource::BiomeTypes, + config: &'a Config, +} + +impl<'a> RegionProcessor<'a> { + pub fn new(config: &'a Config) -> Self { + RegionProcessor { + block_types: resource::BlockTypes::default(), + biome_types: resource::BiomeTypes::default(), + config, + } + } + + /// Parses a filename in the format r.X.Z.mca into the contained X and Z values + fn parse_region_filename(path: &Path) -> Option { + let file_name = path.file_name()?.to_str()?; + let parts: Vec<_> = file_name.split('.').collect(); + let &["r", x, z, "mca"] = parts.as_slice() else { + return None; + }; + + Some((x.parse().ok()?, z.parse().ok()?)) + } + + /// Processes a single chunk + fn process_chunk( + &self, + data: world::de::Chunk, + ) -> Result< + Option<( + ( + Box, + Box, + ), + Box, + )>, + > { + let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; + world::layer::top_layer(&chunk) + } + + fn chunk_lightmap(block_light: Box) -> image::GrayAlphaImage { + const N: u32 = BLOCKS_PER_CHUNK as u32; + + image::GrayAlphaImage::from_fn(N, N, |x, z| { + let v: f32 = block_light[LayerBlockCoords { + x: BlockX(x as u8), + z: BlockZ(z as u8), + }] + .into(); + image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) + }) + } + + fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { + let tmp_path = self.config.processed_path(coords, true); + storage::write(&tmp_path, processed_region)?; + + let output_path = self.config.processed_path(coords, false); + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; + + Ok(()) + } + + fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { + let tmp_path = self.config.light_path(coords, true); + lightmap + .save_with_format(&tmp_path, image::ImageFormat::Png) + .context("Failed to save image")?; + + let output_path = self.config.light_path(coords, false); + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; + + Ok(()) + } + + /// Processes a single region file + fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + println!("Processing region r.{}.{}.mca", coords.0, coords.1); + + let mut processed_region = ProcessedRegion::default(); + let mut lightmap = image::GrayAlphaImage::new(N, N); + + minedmap::io::region::from_file(path)?.foreach_chunk( + |chunk_coords, data: world::de::Chunk| { + let Some((processed_chunk, block_light)) = self + .process_chunk(data) + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + else { + return Ok(()); + }; + processed_region[chunk_coords] = Some(processed_chunk); + + let chunk_lightmap = Self::chunk_lightmap(block_light); + overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); + + Ok(()) + }, + )?; + + self.save_region(coords, &processed_region)?; + self.save_lightmap(coords, &lightmap)?; + + Ok(()) + } + + /// Iterates over all region files of a Minecraft save directory + /// + /// Returns a list of the coordinates of all processed regions + pub fn run(self) -> Result> { + let read_dir = self.config.region_dir.read_dir().with_context(|| { + format!( + "Failed to read directory {}", + self.config.region_dir.display() + ) + })?; + + fs::create_dir_all(&self.config.processed_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.config.processed_dir.display(), + ) + })?; + fs::create_dir_all(&self.config.light_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.config.light_dir.display(), + ) + })?; + + let mut ret = Vec::new(); + + for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { + // We are only interested in regular files + entry + .file_type() + .map(|file_type| file_type.is_file()) + .unwrap_or_default() + }) { + let path = entry.path(); + let Some(coords) = Self::parse_region_filename(&path) else { + continue; + }; + + if let Err(err) = self.process_region(&path, coords) { + eprintln!( + "Failed to process region {}: {:?}", + path.file_name().unwrap_or_default().to_string_lossy(), + err, + ); + } + + ret.push(coords); + } + + Ok(ret) + } +} diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs new file mode 100644 index 0000000..4a7b511 --- /dev/null +++ b/src/bin/minedmap/tile_renderer.rs @@ -0,0 +1,113 @@ +use std::fs; + +use anyhow::{Context, Result}; + +use minedmap::{io::storage, resource::Biome, types::*, world}; + +use super::common::*; + +pub struct TileRenderer<'a> { + config: &'a Config, +} + +impl<'a> TileRenderer<'a> { + pub fn new(config: &'a Config) -> Self { + TileRenderer { config } + } + + fn load_region(&self, coords: RegionCoords) -> Result { + let processed_path = self.config.processed_path(coords, false); + storage::read(&processed_path).context("Failed to load processed region data") + } + + fn block_color(block: &world::layer::BlockInfo, _biome: &Biome) -> [u8; 4] { + let h = block + .depth + .map(|depth| 0.5 + 0.005 * depth.0 as f32) + .unwrap_or_default(); + let c = block + .block_type + .color + .0 + .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); + [c[0], c[1], c[2], 255] + } + + fn render_chunk( + image: &mut image::RgbaImage, + coords: ChunkCoords, + blocks: &world::layer::BlockInfoArray, + biomes: &world::layer::BiomeArray, + ) { + const N: u32 = BLOCKS_PER_CHUNK as u32; + + let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { + let coords = LayerBlockCoords { + x: BlockX(x as u8), + z: BlockZ(z as u8), + }; + image::Rgba(match (&blocks[coords], &biomes[coords]) { + (Some(block), Some(biome)) => Self::block_color(block, biome), + _ => [0, 0, 0, 0], + }) + }); + overlay_chunk(image, &chunk_image, coords); + } + + fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { + for (coords, chunk) in region.iter() { + let Some((blocks, biomes)) = chunk else { + continue; + }; + + Self::render_chunk(image, coords, blocks, biomes); + } + } + + fn render_tile(&self, coords: RegionCoords) -> Result<()> { + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let tmp_path = self.config.map_path(coords, true); + let output_path = self.config.map_path(coords, false); + println!( + "Rendering tile {}", + output_path + .file_name() + .unwrap_or_default() + .to_string_lossy(), + ); + + let region = self.load_region(coords)?; + let mut image = image::RgbaImage::new(N, N); + Self::render_region(&mut image, ®ion); + image + .save_with_format(&tmp_path, image::ImageFormat::Png) + .context("Failed to save image")?; + fs::rename(&tmp_path, &output_path).with_context(|| { + format!( + "Failed to rename {} to {}", + tmp_path.display(), + output_path.display(), + ) + })?; + + Ok(()) + } + + pub fn run(self, regions: &[RegionCoords]) -> Result<()> { + fs::create_dir_all(&self.config.map_dir).with_context(|| { + format!( + "Failed to create directory {}", + self.config.map_dir.display(), + ) + })?; + + for &coords in regions { + if let Err(err) = self.render_tile(coords) { + eprintln!("Failed to render tile {:?}: {:?}", coords, err,); + } + } + + Ok(()) + } +} From 2dd9283d95a312b56c7f15056dae7928888dcedf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 1 May 2023 17:51:38 +0200 Subject: [PATCH 163/460] minedmap: move some internal functions out of impl blocks --- src/bin/minedmap/region_processor.rs | 30 +++++++++++++++------------- src/bin/minedmap/tile_renderer.rs | 28 +++++++++++++------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 640467c..e410013 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -6,6 +6,17 @@ use minedmap::{io::storage, resource, types::*, world}; use super::common::*; +/// Parses a filename in the format r.X.Z.mca into the contained X and Z values +fn parse_region_filename(path: &Path) -> Option { + let file_name = path.file_name()?.to_str()?; + let parts: Vec<_> = file_name.split('.').collect(); + let &["r", x, z, "mca"] = parts.as_slice() else { + return None; + }; + + Some((x.parse().ok()?, z.parse().ok()?)) +} + /// Type with methods for processing the regions of a Minecraft save directory pub struct RegionProcessor<'a> { block_types: resource::BlockTypes, @@ -22,17 +33,6 @@ impl<'a> RegionProcessor<'a> { } } - /// Parses a filename in the format r.X.Z.mca into the contained X and Z values - fn parse_region_filename(path: &Path) -> Option { - let file_name = path.file_name()?.to_str()?; - let parts: Vec<_> = file_name.split('.').collect(); - let &["r", x, z, "mca"] = parts.as_slice() else { - return None; - }; - - Some((x.parse().ok()?, z.parse().ok()?)) - } - /// Processes a single chunk fn process_chunk( &self, @@ -50,7 +50,9 @@ impl<'a> RegionProcessor<'a> { world::layer::top_layer(&chunk) } - fn chunk_lightmap(block_light: Box) -> image::GrayAlphaImage { + fn render_chunk_lightmap( + block_light: Box, + ) -> image::GrayAlphaImage { const N: u32 = BLOCKS_PER_CHUNK as u32; image::GrayAlphaImage::from_fn(N, N, |x, z| { @@ -116,7 +118,7 @@ impl<'a> RegionProcessor<'a> { }; processed_region[chunk_coords] = Some(processed_chunk); - let chunk_lightmap = Self::chunk_lightmap(block_light); + let chunk_lightmap = Self::render_chunk_lightmap(block_light); overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); Ok(()) @@ -163,7 +165,7 @@ impl<'a> RegionProcessor<'a> { .unwrap_or_default() }) { let path = entry.path(); - let Some(coords) = Self::parse_region_filename(&path) else { + let Some(coords) = parse_region_filename(&path) else { continue; }; diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 4a7b511..fcd3e85 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -6,6 +6,19 @@ use minedmap::{io::storage, resource::Biome, types::*, world}; use super::common::*; +fn block_color(block: &world::layer::BlockInfo, _biome: &Biome) -> [u8; 4] { + let h = block + .depth + .map(|depth| 0.5 + 0.005 * depth.0 as f32) + .unwrap_or_default(); + let c = block + .block_type + .color + .0 + .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); + [c[0], c[1], c[2], 255] +} + pub struct TileRenderer<'a> { config: &'a Config, } @@ -20,19 +33,6 @@ impl<'a> TileRenderer<'a> { storage::read(&processed_path).context("Failed to load processed region data") } - fn block_color(block: &world::layer::BlockInfo, _biome: &Biome) -> [u8; 4] { - let h = block - .depth - .map(|depth| 0.5 + 0.005 * depth.0 as f32) - .unwrap_or_default(); - let c = block - .block_type - .color - .0 - .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); - [c[0], c[1], c[2], 255] - } - fn render_chunk( image: &mut image::RgbaImage, coords: ChunkCoords, @@ -47,7 +47,7 @@ impl<'a> TileRenderer<'a> { z: BlockZ(z as u8), }; image::Rgba(match (&blocks[coords], &biomes[coords]) { - (Some(block), Some(biome)) => Self::block_color(block, biome), + (Some(block), Some(biome)) => block_color(block, biome), _ => [0, 0, 0, 0], }) }); From e801631561c6163fbef4bdbba5bab2560e3edbf7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 May 2023 20:56:39 +0200 Subject: [PATCH 164/460] Update dependencies --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7531593..931bdf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anstream" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", @@ -119,9 +119,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.5" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a1f23fa97e1d1641371b51f35535cb26959b8e27ab50d167a8b996b5bada819" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" dependencies = [ "clap_builder", "clap_derive", @@ -130,9 +130,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.5" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdc5d93c358224b4d6867ef1356d740de2303e9892edc06c5340daeccd96bab" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" dependencies = [ "anstream", "anstyle", @@ -353,9 +353,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "minedmap" @@ -423,9 +423,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" @@ -460,9 +460,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.18" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", From 25710bb1ed7b2309b5d97ab197175c7046f00310 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 May 2023 20:53:06 +0200 Subject: [PATCH 165/460] Move block_color() to new module --- src/bin/minedmap/tile_renderer.rs | 24 +++++++++--------------- src/resource/block_color.rs | 10 ++++++++++ src/resource/mod.rs | 2 ++ 3 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 src/resource/block_color.rs diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index fcd3e85..64c9d55 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -2,23 +2,10 @@ use std::fs; use anyhow::{Context, Result}; -use minedmap::{io::storage, resource::Biome, types::*, world}; +use minedmap::{io::storage, resource::block_color, types::*, world}; use super::common::*; -fn block_color(block: &world::layer::BlockInfo, _biome: &Biome) -> [u8; 4] { - let h = block - .depth - .map(|depth| 0.5 + 0.005 * depth.0 as f32) - .unwrap_or_default(); - let c = block - .block_type - .color - .0 - .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); - [c[0], c[1], c[2], 255] -} - pub struct TileRenderer<'a> { config: &'a Config, } @@ -47,7 +34,14 @@ impl<'a> TileRenderer<'a> { z: BlockZ(z as u8), }; image::Rgba(match (&blocks[coords], &biomes[coords]) { - (Some(block), Some(biome)) => block_color(block, biome), + ( + Some(world::layer::BlockInfo { + block_type, + depth: Some(depth), + .. + }), + Some(biome), + ) => block_color(*block_type, biome, depth.0 as f32), _ => [0, 0, 0, 0], }) }); diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs new file mode 100644 index 0000000..31434de --- /dev/null +++ b/src/resource/block_color.rs @@ -0,0 +1,10 @@ +use super::{Biome, BlockType}; + +pub fn block_color(block: BlockType, _biome: &Biome, depth: f32) -> [u8; 4] { + let h = 0.5 + 0.005 * depth; + let c = block + .color + .0 + .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); + [c[0], c[1], c[2], 255] +} diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 62c5d9c..a1abaf8 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -1,4 +1,5 @@ mod biomes; +mod block_color; mod block_types; mod legacy_block_types; @@ -90,6 +91,7 @@ impl BlockTypes { } pub use biomes::Biome; +pub use block_color::block_color; #[derive(Debug)] pub struct BiomeTypes { From b66bdf5ce10c1345a9f699fde03d15aa7e91e8a1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 May 2023 22:08:33 +0200 Subject: [PATCH 166/460] resource: implement water/foliage/grass color computation --- Cargo.lock | 7 +++ Cargo.toml | 1 + src/resource/biomes.rs | 12 +++++ src/resource/block_color.rs | 101 +++++++++++++++++++++++++++++++++--- src/resource/mod.rs | 2 +- 5 files changed, 114 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 931bdf6..3c53295 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,6 +268,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "glam" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad83ab008a4fa3b31dfa713dd41b5a9bdea1e94e4cf1e2fc274ffbd49b0271d3" + [[package]] name = "heck" version = "0.4.1" @@ -368,6 +374,7 @@ dependencies = [ "enumflags2", "fastnbt", "flate2", + "glam", "image", "itertools", "num-integer", diff --git a/Cargo.toml b/Cargo.toml index 9a82052..59b435c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ clap = { version = "4.1.4", features = ["derive"] } enumflags2 = "0.7.5" fastnbt = "2.3.2" flate2 = "1.0.25" +glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } itertools = "0.10.5" num-integer = "0.1.45" diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs index 036cafc..cf0db4b 100644 --- a/src/resource/biomes.rs +++ b/src/resource/biomes.rs @@ -60,6 +60,18 @@ impl Biome { ..self } } + + fn decode(val: i8) -> f32 { + f32::from(val) / 20.0 + } + + pub fn temp(&self) -> f32 { + Self::decode(self.temp) + } + + pub fn downfall(&self) -> f32 { + Self::decode(self.downfall) + } } // Data extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index 31434de..21cd5c7 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -1,10 +1,95 @@ -use super::{Biome, BlockType}; +use super::{Biome, BlockType, Color}; -pub fn block_color(block: BlockType, _biome: &Biome, depth: f32) -> [u8; 4] { - let h = 0.5 + 0.005 * depth; - let c = block - .color - .0 - .map(|v| (f32::from(v) * h).clamp(0.0, 255.0) as u8); - [c[0], c[1], c[2], 255] +use glam::Vec3; + +fn color_vec(color: Color) -> Vec3 { + Vec3::from_array(color.0.map(f32::from)) +} + +fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { + let temp = (biome.temp() - f32::max((depth - 64.0) / 600.0, 0.0)).clamp(0.0, 1.0); + let downfall = biome.downfall().clamp(0.0, 1.0) * temp; + + colors[0] + temp * colors[1] + downfall * colors[2] +} + +trait BiomeExt { + fn grass_color(&self, depth: f32) -> Vec3; + fn foliage_color(&self, depth: f32) -> Vec3; + fn water_color(&self) -> Vec3; +} + +impl BiomeExt for Biome { + fn grass_color(&self, depth: f32) -> Vec3 { + const GRASS_COLORS: [Vec3; 3] = [ + Vec3::new(0.502, 0.706, 0.592), // lower right + Vec3::new(0.247, 0.012, -0.259), // lower left - lower right + Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left + ]; + + self.grass_color + .map(color_vec) + .unwrap_or_else(|| color_from_params(&GRASS_COLORS, self, depth)) + } + + fn foliage_color(&self, depth: f32) -> Vec3 { + use super::BiomeGrassColorModifier::*; + + const FOLIAGE_COLORS: [Vec3; 3] = [ + Vec3::new(0.502, 0.706, 0.592), // lower right + Vec3::new(0.247, 0.012, -0.259), // lower left - lower right + Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left + ]; + const DARK_FOREST_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) + const SWAMP_FOLIAGE_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) + + let regular_color = || { + self.foliage_color + .map(color_vec) + .unwrap_or_else(|| color_from_params(&FOLIAGE_COLORS, self, depth)) + }; + + match self.grass_color_modifier { + Some(DarkForest) => 0.5 * (regular_color() + DARK_FOREST_COLOR), + Some(Swamp) => SWAMP_FOLIAGE_COLOR, + None => regular_color(), + } + } + + fn water_color(&self) -> Vec3 { + const DEFAULT_WATER_COLOR: Vec3 = Vec3::new(0.247, 0.463, 0.894); // == color_vec(Color([63, 118, 228])) + + self.water_color + .map(color_vec) + .unwrap_or(DEFAULT_WATER_COLOR) + } +} + +const BIRCH_COLOR: Vec3 = Vec3::new(0.502, 0.655, 0.333); // == color_vec(Color([128, 167, 85])) +const EVERGREEN_COLOR: Vec3 = Vec3::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) + +pub fn block_color(block: BlockType, biome: &Biome, depth: f32) -> [u8; 4] { + use super::BlockFlag::*; + + let mut color = color_vec(block.color); + + if block.is(Grass) { + color *= biome.grass_color(depth); + } + if block.is(Foliage) { + color *= biome.foliage_color(depth); + } + if block.is(Birch) { + color *= BIRCH_COLOR; + } + if block.is(Spruce) { + color *= EVERGREEN_COLOR; + } + if block.is(Water) { + color *= biome.water_color(); + } + + color *= 0.5 + 0.005 * depth; + + [color[0] as u8, color[1] as u8, color[2] as u8, 255] } diff --git a/src/resource/mod.rs b/src/resource/mod.rs index a1abaf8..7095f68 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -90,7 +90,7 @@ impl BlockTypes { } } -pub use biomes::Biome; +pub use biomes::{Biome, BiomeGrassColorModifier}; pub use block_color::block_color; #[derive(Debug)] From 924ee01f9188878d6ee7ad940ba81f16a132785a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 May 2023 23:04:06 +0200 Subject: [PATCH 167/460] world/layer: introduce LayerData struct to fix clippy type complexity warning --- src/bin/minedmap/region_processor.rs | 26 ++++++++++---------------- src/world/layer.rs | 23 +++++++++++++---------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index e410013..415cca0 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -2,7 +2,12 @@ use std::{fs, path::Path}; use anyhow::{Context, Result}; -use minedmap::{io::storage, resource, types::*, world}; +use minedmap::{ + io::storage, + resource, + types::*, + world::{self, layer::LayerData}, +}; use super::common::*; @@ -34,18 +39,7 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single chunk - fn process_chunk( - &self, - data: world::de::Chunk, - ) -> Result< - Option<( - ( - Box, - Box, - ), - Box, - )>, - > { + fn process_chunk(&self, data: world::de::Chunk) -> Result> { let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; world::layer::top_layer(&chunk) } @@ -110,15 +104,15 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some((processed_chunk, block_light)) = self + let Some(layer_data) = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { return Ok(()); }; - processed_region[chunk_coords] = Some(processed_chunk); + processed_region[chunk_coords] = Some((layer_data.blocks, layer_data.biomes)); - let chunk_lightmap = Self::render_chunk_lightmap(block_light); + let chunk_lightmap = Self::render_chunk_lightmap(layer_data.block_light); overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); Ok(()) diff --git a/src/world/layer.rs b/src/world/layer.rs index a457191..89cff41 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -86,6 +86,13 @@ pub type BlockInfoArray = LayerBlockArray>; pub type BiomeArray = LayerBlockArray>; pub type BlockLightArray = LayerBlockArray; +#[derive(Debug, Default)] +pub struct LayerData { + pub blocks: Box, + pub biomes: Box, + pub block_light: Box, +} + /// Fills in a [BlockInfoArray] with the information of the chunk's top /// block layer /// @@ -93,9 +100,7 @@ pub type BlockLightArray = LayerBlockArray; /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer( - chunk: &Chunk, -) -> Result, Box), Box)>> { +pub fn top_layer(chunk: &Chunk) -> Result> { use BLOCKS_PER_CHUNK as N; if chunk.is_empty() { @@ -103,9 +108,7 @@ pub fn top_layer( } let mut done = 0; - let mut blocks = Box::::default(); - let mut block_biomes = Box::::default(); - let mut light = Box::::default(); + let mut ret = LayerData::default(); for SectionIterItem { y: section_y, @@ -116,7 +119,7 @@ pub fn top_layer( { for y in BlockY::iter().rev() { for xz in BlockInfoArray::keys() { - let entry = &mut blocks[xz]; + let entry = &mut ret.blocks[xz]; if entry.done() { continue; } @@ -137,13 +140,13 @@ pub fn top_layer( done += 1; }; - let biome_entry = &mut block_biomes[xz]; + let biome_entry = &mut ret.biomes[xz]; if !entry.is_none() && biome_entry.is_none() { *biome_entry = biomes.biome_at(section_y, coords)?.copied(); } if entry.is_none() { - light[xz] = block_light.block_light_at(coords); + ret.block_light[xz] = block_light.block_light_at(coords); } if done == N * N { @@ -153,5 +156,5 @@ pub fn top_layer( } } - Ok(Some(((blocks, block_biomes), light))) + Ok(Some(ret)) } From 263fc6d6ced81836d84493ad60807198a05d609c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 May 2023 23:15:34 +0200 Subject: [PATCH 168/460] world/layer: remove unused y coordinate from BlockInfo --- src/world/layer.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index 89cff41..4365e1f 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -28,7 +28,6 @@ impl BlockHeight { #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockInfo { pub block_type: BlockType, - pub y: BlockHeight, pub depth: Option, } @@ -66,7 +65,6 @@ impl OptionBlockInfoExt for Option { if self.is_none() { *self = Some(BlockInfo { block_type, - y, depth: None, }); } From 2d5eec13c2e0b0cb9fea2ba9d8097fba38573e4c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 May 2023 23:29:57 +0200 Subject: [PATCH 169/460] world/layer: move Option into BlockInfo struct Preparation for top_layer() cleanup. --- src/bin/minedmap/tile_renderer.rs | 6 ++-- src/world/layer.rs | 51 +++++++++---------------------- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 64c9d55..ac1193a 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -35,11 +35,11 @@ impl<'a> TileRenderer<'a> { }; image::Rgba(match (&blocks[coords], &biomes[coords]) { ( - Some(world::layer::BlockInfo { - block_type, + world::layer::BlockInfo { + block_type: Some(block_type), depth: Some(depth), .. - }), + }, Some(biome), ) => block_color(*block_type, biome, depth.0 as f32), _ => [0, 0, 0, 0], diff --git a/src/world/layer.rs b/src/world/layer.rs index 4365e1f..7c8b9bb 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -25,36 +25,23 @@ impl BlockHeight { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] pub struct BlockInfo { - pub block_type: BlockType, + pub block_type: Option, pub depth: Option, } -/// Helper methods for [BlockInfo] -trait OptionBlockInfoExt { - /// Checks if a [BlockInfo] has been filled in completely - /// - /// Helper used by [top_layer] - fn done(&self) -> bool; +pub type BlockInfoArray = LayerBlockArray; +pub type BiomeArray = LayerBlockArray>; +pub type BlockLightArray = LayerBlockArray; - /// Fills in a [BlockInfo] based on a [BlockType] - /// - /// Only fills in data if the block is part of the visible top layer - /// of the rendered map. - /// - /// Must be called on an incomplete [BlockInfo] entry. Returns `true` - /// if the entry has been filled in completely. - fn fill(&mut self, y: BlockHeight, block_type: BlockType) -> bool; -} +impl BlockInfo { + fn is_empty(&self) -> bool { + self.block_type.is_none() + } -impl OptionBlockInfoExt for Option { fn done(&self) -> bool { - let Some(info) = self else { - return false; - }; - - info.depth.is_some() + self.depth.is_some() } fn fill(&mut self, y: BlockHeight, block_type: BlockType) -> bool { @@ -62,28 +49,20 @@ impl OptionBlockInfoExt for Option { return false; } - if self.is_none() { - *self = Some(BlockInfo { - block_type, - depth: None, - }); + if self.block_type.is_none() { + self.block_type = Some(block_type); } if block_type.is(BlockFlag::Water) { return false; } - let info = self.as_mut().unwrap(); - info.depth = Some(y); + self.depth = Some(y); true } } -pub type BlockInfoArray = LayerBlockArray>; -pub type BiomeArray = LayerBlockArray>; -pub type BlockLightArray = LayerBlockArray; - #[derive(Debug, Default)] pub struct LayerData { pub blocks: Box, @@ -139,11 +118,11 @@ pub fn top_layer(chunk: &Chunk) -> Result> { }; let biome_entry = &mut ret.biomes[xz]; - if !entry.is_none() && biome_entry.is_none() { + if !entry.is_empty() && biome_entry.is_none() { *biome_entry = biomes.biome_at(section_y, coords)?.copied(); } - if entry.is_none() { + if entry.is_empty() { ret.block_light[xz] = block_light.block_light_at(coords); } From 0437ec70b678da4340d2147c91e66c42fc07bed4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 5 May 2023 23:57:14 +0200 Subject: [PATCH 170/460] world/layer: introduce LayerEntry struct --- src/world/layer.rs | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index 7c8b9bb..e6c0cb0 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -35,9 +35,16 @@ pub type BlockInfoArray = LayerBlockArray; pub type BiomeArray = LayerBlockArray>; pub type BlockLightArray = LayerBlockArray; -impl BlockInfo { +struct LayerEntry<'a> { + block: &'a mut Option, + biome: &'a mut Option, + block_light: &'a mut u8, + depth: &'a mut Option, +} + +impl<'a> LayerEntry<'a> { fn is_empty(&self) -> bool { - self.block_type.is_none() + self.block.is_none() } fn done(&self) -> bool { @@ -49,15 +56,15 @@ impl BlockInfo { return false; } - if self.block_type.is_none() { - self.block_type = Some(block_type); + if self.block.is_none() { + *self.block = Some(block_type); } if block_type.is(BlockFlag::Water) { return false; } - self.depth = Some(y); + *self.depth = Some(y); true } @@ -70,6 +77,18 @@ pub struct LayerData { pub block_light: Box, } +impl LayerData { + fn entry(&mut self, coords: LayerBlockCoords) -> LayerEntry { + let block_info = &mut self.blocks[coords]; + LayerEntry { + block: &mut block_info.block_type, + biome: &mut self.biomes[coords], + block_light: &mut self.block_light[coords], + depth: &mut block_info.depth, + } + } +} + /// Fills in a [BlockInfoArray] with the information of the chunk's top /// block layer /// @@ -96,7 +115,7 @@ pub fn top_layer(chunk: &Chunk) -> Result> { { for y in BlockY::iter().rev() { for xz in BlockInfoArray::keys() { - let entry = &mut ret.blocks[xz]; + let mut entry = ret.entry(xz); if entry.done() { continue; } @@ -117,13 +136,12 @@ pub fn top_layer(chunk: &Chunk) -> Result> { done += 1; }; - let biome_entry = &mut ret.biomes[xz]; - if !entry.is_empty() && biome_entry.is_none() { - *biome_entry = biomes.biome_at(section_y, coords)?.copied(); + if !entry.is_empty() && entry.biome.is_none() { + *entry.biome = biomes.biome_at(section_y, coords)?.copied(); } if entry.is_empty() { - ret.block_light[xz] = block_light.block_light_at(coords); + *entry.block_light = block_light.block_light_at(coords); } if done == N * N { From 0b392d7a3a9ce2fd9fafcb783e00be568323ea54 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 May 2023 00:26:55 +0200 Subject: [PATCH 171/460] world/layer: move more top_layer() logic into LayerEntry::fill() --- src/world/layer.rs | 57 +++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/src/world/layer.rs b/src/world/layer.rs index e6c0cb0..4a5fe46 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -51,22 +51,30 @@ impl<'a> LayerEntry<'a> { self.depth.is_some() } - fn fill(&mut self, y: BlockHeight, block_type: BlockType) -> bool { - if !block_type.is(BlockFlag::Opaque) { - return false; - } + fn fill(&mut self, section: SectionIterItem, coords: SectionBlockCoords) -> Result { + let Some(block_type) = section.section.block_at(coords)? + .filter(|block_type| block_type.is(BlockFlag::Opaque)) + else { + if self.is_empty() { + *self.block_light = section.block_light.block_light_at(coords); + } - if self.block.is_none() { + return Ok(false); + }; + + if self.is_empty() { *self.block = Some(block_type); + *self.biome = section.biomes.biome_at(section.y, coords)?.copied(); } if block_type.is(BlockFlag::Water) { - return false; + return Ok(false); } - *self.depth = Some(y); + let height = BlockHeight::new(section.y, coords.y)?; + *self.depth = Some(height); - true + Ok(true) } } @@ -106,13 +114,7 @@ pub fn top_layer(chunk: &Chunk) -> Result> { let mut done = 0; let mut ret = LayerData::default(); - for SectionIterItem { - y: section_y, - section, - biomes, - block_light, - } in chunk.sections().rev() - { + for section in chunk.sections().rev() { for y in BlockY::iter().rev() { for xz in BlockInfoArray::keys() { let mut entry = ret.entry(xz); @@ -121,29 +123,12 @@ pub fn top_layer(chunk: &Chunk) -> Result> { } let coords = SectionBlockCoords { xz, y }; - - 'check_block: { - let Some(block_type) = section.block_at(coords)? else { - break 'check_block; - }; - - let height = BlockHeight::new(section_y, y)?; - if !entry.fill(height, block_type) { - break 'check_block; - } - - assert!(entry.done()); - done += 1; - }; - - if !entry.is_empty() && entry.biome.is_none() { - *entry.biome = biomes.biome_at(section_y, coords)?.copied(); - } - - if entry.is_empty() { - *entry.block_light = block_light.block_light_at(coords); + if !entry.fill(section, coords)? { + continue; } + assert!(entry.done()); + done += 1; if done == N * N { break; } From 31eb92864ccb253319b8822c9cb89c1f23dc207f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 May 2023 00:44:00 +0200 Subject: [PATCH 172/460] Split up BlockInfo type By storing block types and depth values separately, the processed world data can be compressed better, decreasing data size by ~10%. --- src/bin/minedmap/common.rs | 18 ++++++++------ src/bin/minedmap/region_processor.rs | 15 ++++++++---- src/bin/minedmap/tile_renderer.rs | 36 +++++++++++++--------------- src/world/layer.rs | 19 ++++++--------- 4 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index ae645d1..eda782d 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -1,14 +1,18 @@ use std::path::{Path, PathBuf}; -use minedmap::{types::*, world}; +use serde::{Deserialize, Serialize}; + +use minedmap::{types::*, world::layer}; pub type RegionCoords = (i32, i32); -pub type ProcessedRegion = ChunkArray< - Option<( - Box, - Box, - )>, ->; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ProcessedChunk { + pub blocks: Box, + pub biomes: Box, + pub depths: Box, +} +pub type ProcessedRegion = ChunkArray>; pub struct Config { pub region_dir: PathBuf, diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 415cca0..e1ea187 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -6,7 +6,10 @@ use minedmap::{ io::storage, resource, types::*, - world::{self, layer::LayerData}, + world::{ + self, + layer::{self, LayerData}, + }, }; use super::common::*; @@ -104,15 +107,19 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some(layer_data) = self + let Some(layer::LayerData{ blocks, biomes, block_light, depths }) = self .process_chunk(data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { return Ok(()); }; - processed_region[chunk_coords] = Some((layer_data.blocks, layer_data.biomes)); + processed_region[chunk_coords] = Some(ProcessedChunk { + blocks, + biomes, + depths, + }); - let chunk_lightmap = Self::render_chunk_lightmap(layer_data.block_light); + let chunk_lightmap = Self::render_chunk_lightmap(block_light); overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); Ok(()) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index ac1193a..3ae51c6 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -2,7 +2,7 @@ use std::fs; use anyhow::{Context, Result}; -use minedmap::{io::storage, resource::block_color, types::*, world}; +use minedmap::{io::storage, resource::block_color, types::*}; use super::common::*; @@ -20,12 +20,7 @@ impl<'a> TileRenderer<'a> { storage::read(&processed_path).context("Failed to load processed region data") } - fn render_chunk( - image: &mut image::RgbaImage, - coords: ChunkCoords, - blocks: &world::layer::BlockInfoArray, - biomes: &world::layer::BiomeArray, - ) { + fn render_chunk(image: &mut image::RgbaImage, coords: ChunkCoords, chunk: &ProcessedChunk) { const N: u32 = BLOCKS_PER_CHUNK as u32; let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { @@ -33,28 +28,29 @@ impl<'a> TileRenderer<'a> { x: BlockX(x as u8), z: BlockZ(z as u8), }; - image::Rgba(match (&blocks[coords], &biomes[coords]) { - ( - world::layer::BlockInfo { - block_type: Some(block_type), - depth: Some(depth), - .. - }, - Some(biome), - ) => block_color(*block_type, biome, depth.0 as f32), - _ => [0, 0, 0, 0], - }) + image::Rgba( + match ( + &chunk.blocks[coords], + &chunk.biomes[coords], + &chunk.depths[coords], + ) { + (Some(block), Some(biome), Some(depth)) => { + block_color(*block, biome, depth.0 as f32) + } + _ => [0, 0, 0, 0], + }, + ) }); overlay_chunk(image, &chunk_image, coords); } fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { for (coords, chunk) in region.iter() { - let Some((blocks, biomes)) = chunk else { + let Some(chunk) = chunk else { continue; }; - Self::render_chunk(image, coords, blocks, biomes); + Self::render_chunk(image, coords, chunk); } } diff --git a/src/world/layer.rs b/src/world/layer.rs index 4a5fe46..440c137 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -25,15 +25,10 @@ impl BlockHeight { } } -#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] -pub struct BlockInfo { - pub block_type: Option, - pub depth: Option, -} - -pub type BlockInfoArray = LayerBlockArray; +pub type BlockArray = LayerBlockArray>; pub type BiomeArray = LayerBlockArray>; pub type BlockLightArray = LayerBlockArray; +pub type DepthArray = LayerBlockArray>; struct LayerEntry<'a> { block: &'a mut Option, @@ -80,19 +75,19 @@ impl<'a> LayerEntry<'a> { #[derive(Debug, Default)] pub struct LayerData { - pub blocks: Box, + pub blocks: Box, pub biomes: Box, pub block_light: Box, + pub depths: Box, } impl LayerData { fn entry(&mut self, coords: LayerBlockCoords) -> LayerEntry { - let block_info = &mut self.blocks[coords]; LayerEntry { - block: &mut block_info.block_type, + block: &mut self.blocks[coords], biome: &mut self.biomes[coords], block_light: &mut self.block_light[coords], - depth: &mut block_info.depth, + depth: &mut self.depths[coords], } } } @@ -116,7 +111,7 @@ pub fn top_layer(chunk: &Chunk) -> Result> { for section in chunk.sections().rev() { for y in BlockY::iter().rev() { - for xz in BlockInfoArray::keys() { + for xz in LayerBlockArray::<()>::keys() { let mut entry = ret.entry(xz); if entry.done() { continue; From 42cb342749891d38e8207a09329be54740218d7e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 10 May 2023 00:48:53 +0200 Subject: [PATCH 173/460] world/layer: avoid iproduct-based iterator in inner loop iproduct iterators are fairly slow. As the iterator implementation is now unused, it is removed as well. --- src/types.rs | 14 -------------- src/world/layer.rs | 30 +++++++++++++++++------------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/types.rs b/src/types.rs index 06e01f9..18045bb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -73,20 +73,6 @@ impl LayerBlockCoords { #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); -impl LayerBlockArray { - pub fn keys() -> impl Iterator + Clone + Debug { - iproduct!(BlockZ::iter(), BlockX::iter()).map(|(z, x)| LayerBlockCoords { x, z }) - } - - pub fn values(&self) -> impl Iterator + Clone + Debug { - Self::keys().map(|k| &self[k]) - } - - pub fn iter(&self) -> impl Iterator + Clone + Debug { - Self::keys().map(|k| (k, &self[k])) - } -} - impl Index for LayerBlockArray { type Output = T; diff --git a/src/world/layer.rs b/src/world/layer.rs index 440c137..4b23f26 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -111,21 +111,25 @@ pub fn top_layer(chunk: &Chunk) -> Result> { for section in chunk.sections().rev() { for y in BlockY::iter().rev() { - for xz in LayerBlockArray::<()>::keys() { - let mut entry = ret.entry(xz); - if entry.done() { - continue; - } + for z in BlockZ::iter() { + for x in BlockX::iter() { + let xz = LayerBlockCoords { x, z }; - let coords = SectionBlockCoords { xz, y }; - if !entry.fill(section, coords)? { - continue; - } + let mut entry = ret.entry(xz); + if entry.done() { + continue; + } - assert!(entry.done()); - done += 1; - if done == N * N { - break; + let coords = SectionBlockCoords { xz, y }; + if !entry.fill(section, coords)? { + continue; + } + + assert!(entry.done()); + done += 1; + if done == N * N { + break; + } } } } From 59e919e9eaff7b4b75f341877d45de86d389c031 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 1 Jun 2023 22:53:39 +0200 Subject: [PATCH 174/460] Update dependencies --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c53295..10592be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,9 +119,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.7" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" dependencies = [ "clap_builder", "clap_derive", @@ -130,9 +130,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" dependencies = [ "anstream", "anstyle", @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b" dependencies = [ "heck", "proc-macro2", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "cmake" @@ -302,9 +302,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", @@ -343,9 +343,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.142" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libz-ng-sys" @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "minedmap" @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" [[package]] name = "pkg-config" @@ -449,18 +449,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -481,9 +481,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", @@ -522,9 +522,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.15" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -533,9 +533,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "utf8parse" From 1abb26099772b4c23d03479ed5a76c3547e371dd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 May 2023 16:25:05 +0200 Subject: [PATCH 175/460] io/fs: add new module with filesystem access helpers Wrappers around std::fs with error messages, as well as a create_with_tmpfile() helper. --- src/io/fs.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/mod.rs | 1 + 2 files changed, 62 insertions(+) create mode 100644 src/io/fs.rs diff --git a/src/io/fs.rs b/src/io/fs.rs new file mode 100644 index 0000000..46e8726 --- /dev/null +++ b/src/io/fs.rs @@ -0,0 +1,61 @@ +use std::{ + fs::{self, File}, + io::{BufWriter, Write}, + path::{Path, PathBuf}, +}; + +use anyhow::{Context, Ok, Result}; + +fn tmpfile_name(path: &Path) -> PathBuf { + let mut file_name = path.file_name().unwrap_or_default().to_os_string(); + file_name.push(".tmp"); + + let mut ret = path.to_path_buf(); + ret.set_file_name(file_name); + ret +} + +pub fn create_dir_all(path: &Path) -> Result<()> { + fs::create_dir_all(path) + .with_context(|| format!("Failed to create directory {}", path.display(),)) +} + +pub fn rename(from: &Path, to: &Path) -> Result<()> { + fs::rename(from, to) + .with_context(|| format!("Failed to rename {} to {}", from.display(), to.display())) +} + +pub fn create(path: &Path, f: F) -> Result +where + F: FnOnce(&mut BufWriter) -> Result, +{ + (|| { + let file = File::create(path)?; + let mut writer = BufWriter::new(file); + + let ret = f(&mut writer)?; + writer.flush()?; + + Ok(ret) + })() + .with_context(|| format!("Failed to write file {}", path.display())) +} + +pub fn create_with_tmpfile(path: &Path, f: F) -> Result +where + F: FnOnce(&mut BufWriter) -> Result, +{ + let tmp_path = tmpfile_name(path); + + let ret = (|| { + let ret = create(&tmp_path, f)?; + rename(&tmp_path, path)?; + Ok(ret) + })(); + + if ret.is_err() { + let _ = fs::remove_file(&tmp_path); + } + + ret +} diff --git a/src/io/mod.rs b/src/io/mod.rs index 4098f3b..681d75d 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,3 +1,4 @@ pub mod data; +pub mod fs; pub mod region; pub mod storage; From 587db0464c064f2f29c974216f1ca464c7d54068 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 May 2023 16:32:13 +0200 Subject: [PATCH 176/460] io/storage: use fs::create_with_tmpfile() helper --- src/bin/minedmap/region_processor.rs | 13 +------------ src/io/storage.rs | 9 ++++----- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index e1ea187..d81994f 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -63,19 +63,8 @@ impl<'a> RegionProcessor<'a> { } fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { - let tmp_path = self.config.processed_path(coords, true); - storage::write(&tmp_path, processed_region)?; - let output_path = self.config.processed_path(coords, false); - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - - Ok(()) + storage::write(&output_path, processed_region) } fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { diff --git a/src/io/storage.rs b/src/io/storage.rs index f4b2eed..c1a9e5e 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -7,21 +7,20 @@ use std::{ use anyhow::{Context, Result}; use serde::{de::DeserializeOwned, Serialize}; +use super::fs; + pub fn write(path: &Path, value: &T) -> Result<()> { - (|| -> Result<()> { + fs::create_with_tmpfile(path, |file| { let data = bincode::serialize(value)?; let len = u32::try_from(data.len())?; let compressed = zstd::bulk::compress(&data, 1)?; drop(data); - let mut file = File::create(path)?; file.write_all(&len.to_be_bytes())?; file.write_all(&compressed)?; - file.flush()?; Ok(()) - })() - .with_context(|| format!("Failed to write file {}", path.display())) + }) } pub fn read(path: &Path) -> Result { From 17a02dc74c930a81a1b353aaed4c092b0bb71145 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 7 May 2023 16:38:52 +0200 Subject: [PATCH 177/460] minedmap: use fs helpers --- src/bin/minedmap/common.rs | 31 +++++++-------------- src/bin/minedmap/region_processor.rs | 40 +++++++--------------------- src/bin/minedmap/tile_renderer.rs | 37 ++++++++++--------------- 3 files changed, 34 insertions(+), 74 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index eda782d..764fe4c 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -21,6 +21,10 @@ pub struct Config { pub map_dir: PathBuf, } +fn coord_filename(coords: RegionCoords, ext: &str) -> String { + format!("r.{}.{}.{}", coords.0, coords.1, ext) +} + impl Config { pub fn new(args: super::Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); @@ -36,33 +40,18 @@ impl Config { } } - pub fn processed_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.bin{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); + pub fn processed_path(&self, coords: RegionCoords) -> PathBuf { + let filename = coord_filename(coords, "bin"); [&self.processed_dir, Path::new(&filename)].iter().collect() } - pub fn light_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.png{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); + pub fn light_path(&self, coords: RegionCoords) -> PathBuf { + let filename = coord_filename(coords, "png"); [&self.light_dir, Path::new(&filename)].iter().collect() } - pub fn map_path(&self, coords: RegionCoords, temp: bool) -> PathBuf { - let filename = format!( - "r.{}.{}.png{}", - coords.0, - coords.1, - if temp { ".tmp" } else { "" }, - ); + pub fn map_path(&self, coords: RegionCoords) -> PathBuf { + let filename = coord_filename(coords, "png"); [&self.map_dir, Path::new(&filename)].iter().collect() } } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index d81994f..03229be 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,9 +1,9 @@ -use std::{fs, path::Path}; +use std::path::Path; use anyhow::{Context, Result}; use minedmap::{ - io::storage, + io::{fs, storage}, resource, types::*, world::{ @@ -63,26 +63,16 @@ impl<'a> RegionProcessor<'a> { } fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { - let output_path = self.config.processed_path(coords, false); + let output_path = self.config.processed_path(coords); storage::write(&output_path, processed_region) } fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { - let tmp_path = self.config.light_path(coords, true); - lightmap - .save_with_format(&tmp_path, image::ImageFormat::Png) - .context("Failed to save image")?; - - let output_path = self.config.light_path(coords, false); - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - - Ok(()) + fs::create_with_tmpfile(&self.config.light_path(coords), |file| { + lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) } /// Processes a single region file @@ -132,18 +122,8 @@ impl<'a> RegionProcessor<'a> { ) })?; - fs::create_dir_all(&self.config.processed_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.processed_dir.display(), - ) - })?; - fs::create_dir_all(&self.config.light_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.light_dir.display(), - ) - })?; + fs::create_dir_all(&self.config.processed_dir)?; + fs::create_dir_all(&self.config.light_dir)?; let mut ret = Vec::new(); diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 3ae51c6..b4f4a3a 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,8 +1,10 @@ -use std::fs; - use anyhow::{Context, Result}; -use minedmap::{io::storage, resource::block_color, types::*}; +use minedmap::{ + io::{fs, storage}, + resource::block_color, + types::*, +}; use super::common::*; @@ -16,7 +18,7 @@ impl<'a> TileRenderer<'a> { } fn load_region(&self, coords: RegionCoords) -> Result { - let processed_path = self.config.processed_path(coords, false); + let processed_path = self.config.processed_path(coords); storage::read(&processed_path).context("Failed to load processed region data") } @@ -57,8 +59,8 @@ impl<'a> TileRenderer<'a> { fn render_tile(&self, coords: RegionCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - let tmp_path = self.config.map_path(coords, true); - let output_path = self.config.map_path(coords, false); + let output_path = self.config.map_path(coords); + println!( "Rendering tile {}", output_path @@ -70,27 +72,16 @@ impl<'a> TileRenderer<'a> { let region = self.load_region(coords)?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion); - image - .save_with_format(&tmp_path, image::ImageFormat::Png) - .context("Failed to save image")?; - fs::rename(&tmp_path, &output_path).with_context(|| { - format!( - "Failed to rename {} to {}", - tmp_path.display(), - output_path.display(), - ) - })?; - Ok(()) + fs::create_with_tmpfile(&output_path, |file| { + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) } pub fn run(self, regions: &[RegionCoords]) -> Result<()> { - fs::create_dir_all(&self.config.map_dir).with_context(|| { - format!( - "Failed to create directory {}", - self.config.map_dir.display(), - ) - })?; + fs::create_dir_all(&self.config.map_dir)?; for &coords in regions { if let Err(err) = self.render_tile(coords) { From dede21806c4114208fa7edac194169aa7a35038e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 1 Jul 2023 23:05:39 +0200 Subject: [PATCH 178/460] Update dependencies --- Cargo.lock | 100 ++++++++++++++++++++++++----------------------------- Cargo.toml | 2 +- 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10592be..d8fac2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,15 +25,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -84,6 +84,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "bytemuck" version = "1.13.1" @@ -119,9 +125,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.0" +version = "4.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" +checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" dependencies = [ "clap_builder", "clap_derive", @@ -130,22 +136,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.0" +version = "4.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" +checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", "proc-macro2", @@ -270,9 +275,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad83ab008a4fa3b31dfa713dd41b5a9bdea1e94e4cf1e2fc274ffbd49b0271d3" +checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226" [[package]] name = "heck" @@ -300,34 +305,22 @@ dependencies = [ "png", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" dependencies = [ "hermit-abi", - "io-lifetimes", "rustix", "windows-sys", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -343,9 +336,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libz-ng-sys" @@ -359,9 +352,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "minedmap" @@ -424,9 +417,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.2" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "pkg-config" @@ -436,11 +429,11 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -449,31 +442,30 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] [[package]] name = "rustix" -version = "0.37.19" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3" dependencies = [ - "bitflags", + "bitflags 2.3.3", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -481,9 +473,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] @@ -499,9 +491,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -522,9 +514,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.18" +version = "2.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" dependencies = [ "proc-macro2", "quote", @@ -554,9 +546,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", diff --git a/Cargo.toml b/Cargo.toml index 59b435c..60a20cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ fastnbt = "2.3.2" flate2 = "1.0.25" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } -itertools = "0.10.5" +itertools = "0.11.0" num-integer = "0.1.45" serde = "1.0.152" zstd = "0.12.3" From 007ce010d4400108a9f628a91cefb810805dc276 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 15:11:16 +0200 Subject: [PATCH 179/460] minedmap: rename RegionCoords to TileCoords With mipmapping, coords will not always correspond to regions anymore. --- src/bin/minedmap/common.rs | 10 +++++----- src/bin/minedmap/region_processor.rs | 10 +++++----- src/bin/minedmap/tile_renderer.rs | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 764fe4c..c3e0c0e 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use minedmap::{types::*, world::layer}; -pub type RegionCoords = (i32, i32); +pub type TileCoords = (i32, i32); #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProcessedChunk { @@ -21,7 +21,7 @@ pub struct Config { pub map_dir: PathBuf, } -fn coord_filename(coords: RegionCoords, ext: &str) -> String { +fn coord_filename(coords: TileCoords, ext: &str) -> String { format!("r.{}.{}.{}", coords.0, coords.1, ext) } @@ -40,17 +40,17 @@ impl Config { } } - pub fn processed_path(&self, coords: RegionCoords) -> PathBuf { + pub fn processed_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "bin"); [&self.processed_dir, Path::new(&filename)].iter().collect() } - pub fn light_path(&self, coords: RegionCoords) -> PathBuf { + pub fn light_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "png"); [&self.light_dir, Path::new(&filename)].iter().collect() } - pub fn map_path(&self, coords: RegionCoords) -> PathBuf { + pub fn map_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "png"); [&self.map_dir, Path::new(&filename)].iter().collect() } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 03229be..a942817 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -15,7 +15,7 @@ use minedmap::{ use super::common::*; /// Parses a filename in the format r.X.Z.mca into the contained X and Z values -fn parse_region_filename(path: &Path) -> Option { +fn parse_region_filename(path: &Path) -> Option { let file_name = path.file_name()?.to_str()?; let parts: Vec<_> = file_name.split('.').collect(); let &["r", x, z, "mca"] = parts.as_slice() else { @@ -62,12 +62,12 @@ impl<'a> RegionProcessor<'a> { }) } - fn save_region(&self, coords: RegionCoords, processed_region: &ProcessedRegion) -> Result<()> { + fn save_region(&self, coords: TileCoords, processed_region: &ProcessedRegion) -> Result<()> { let output_path = self.config.processed_path(coords); storage::write(&output_path, processed_region) } - fn save_lightmap(&self, coords: RegionCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { + fn save_lightmap(&self, coords: TileCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { fs::create_with_tmpfile(&self.config.light_path(coords), |file| { lightmap .write_to(file, image::ImageFormat::Png) @@ -76,7 +76,7 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single region file - fn process_region(&self, path: &Path, coords: RegionCoords) -> Result<()> { + fn process_region(&self, path: &Path, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; println!("Processing region r.{}.{}.mca", coords.0, coords.1); @@ -114,7 +114,7 @@ impl<'a> RegionProcessor<'a> { /// Iterates over all region files of a Minecraft save directory /// /// Returns a list of the coordinates of all processed regions - pub fn run(self) -> Result> { + pub fn run(self) -> Result> { let read_dir = self.config.region_dir.read_dir().with_context(|| { format!( "Failed to read directory {}", diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index b4f4a3a..ef23547 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -17,7 +17,7 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } - fn load_region(&self, coords: RegionCoords) -> Result { + fn load_region(&self, coords: TileCoords) -> Result { let processed_path = self.config.processed_path(coords); storage::read(&processed_path).context("Failed to load processed region data") } @@ -56,7 +56,7 @@ impl<'a> TileRenderer<'a> { } } - fn render_tile(&self, coords: RegionCoords) -> Result<()> { + fn render_tile(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let output_path = self.config.map_path(coords); @@ -80,7 +80,7 @@ impl<'a> TileRenderer<'a> { }) } - pub fn run(self, regions: &[RegionCoords]) -> Result<()> { + pub fn run(self, regions: &[TileCoords]) -> Result<()> { fs::create_dir_all(&self.config.map_dir)?; for &coords in regions { From e5c96ecb99e90aed1d72d09753372264b8b52bb2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 15:45:18 +0200 Subject: [PATCH 180/460] minedmap: replace TileCoords type alias with a struct --- src/bin/minedmap/common.rs | 19 ++++++++++++++++--- src/bin/minedmap/region_processor.rs | 7 +++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index c3e0c0e..8d64171 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -1,10 +1,23 @@ -use std::path::{Path, PathBuf}; +use std::{ + fmt::Debug, + path::{Path, PathBuf}, +}; use serde::{Deserialize, Serialize}; use minedmap::{types::*, world::layer}; -pub type TileCoords = (i32, i32); +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct TileCoords { + pub x: i32, + pub z: i32, +} + +impl Debug for TileCoords { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {})", self.x, self.z) + } +} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProcessedChunk { @@ -22,7 +35,7 @@ pub struct Config { } fn coord_filename(coords: TileCoords, ext: &str) -> String { - format!("r.{}.{}.{}", coords.0, coords.1, ext) + format!("r.{}.{}.{}", coords.x, coords.z, ext) } impl Config { diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index a942817..6072636 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -22,7 +22,10 @@ fn parse_region_filename(path: &Path) -> Option { return None; }; - Some((x.parse().ok()?, z.parse().ok()?)) + Some(TileCoords { + x: x.parse().ok()?, + z: z.parse().ok()?, + }) } /// Type with methods for processing the regions of a Minecraft save directory @@ -79,7 +82,7 @@ impl<'a> RegionProcessor<'a> { fn process_region(&self, path: &Path, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - println!("Processing region r.{}.{}.mca", coords.0, coords.1); + println!("Processing region r.{}.{}.mca", coords.x, coords.z); let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); From b53d34da3d0eae697491b7e4ffc40b828b9b0b9a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 18:16:35 +0200 Subject: [PATCH 181/460] minedmap: store region list in BTreeSet We want to have a sorted list in the end anyways to make metadata generation deterministic, and we don't have to worry about deduplication of coordinates when generating mipmap tile lists. --- src/bin/minedmap/main.rs | 2 +- src/bin/minedmap/region_processor.rs | 8 ++++---- src/bin/minedmap/tile_renderer.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index d0714ef..3aef0f8 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -24,7 +24,7 @@ fn main() -> Result<()> { let config = Config::new(args); let regions = RegionProcessor::new(&config).run()?; - TileRenderer::new(&config).run(®ions)?; + TileRenderer::new(&config).run(regions.iter().copied())?; Ok(()) } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 6072636..661c92a 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::{collections::BTreeSet, path::Path}; use anyhow::{Context, Result}; @@ -117,7 +117,7 @@ impl<'a> RegionProcessor<'a> { /// Iterates over all region files of a Minecraft save directory /// /// Returns a list of the coordinates of all processed regions - pub fn run(self) -> Result> { + pub fn run(self) -> Result> { let read_dir = self.config.region_dir.read_dir().with_context(|| { format!( "Failed to read directory {}", @@ -128,7 +128,7 @@ impl<'a> RegionProcessor<'a> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.light_dir)?; - let mut ret = Vec::new(); + let mut ret = BTreeSet::new(); for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { // We are only interested in regular files @@ -150,7 +150,7 @@ impl<'a> RegionProcessor<'a> { ); } - ret.push(coords); + ret.insert(coords); } Ok(ret) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index ef23547..02376c7 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -80,10 +80,10 @@ impl<'a> TileRenderer<'a> { }) } - pub fn run(self, regions: &[TileCoords]) -> Result<()> { + pub fn run(self, regions: impl IntoIterator) -> Result<()> { fs::create_dir_all(&self.config.map_dir)?; - for &coords in regions { + for coords in regions { if let Err(err) = self.render_tile(coords) { eprintln!("Failed to render tile {:?}: {:?}", coords, err,); } From b1f7f759f1db209ca957d027831d8765af7ce56a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 18:51:17 +0200 Subject: [PATCH 182/460] minedmap: introduce generic tile path function, pass mipmap level --- src/bin/minedmap/common.rs | 29 +++++++++++++++++----------- src/bin/minedmap/region_processor.rs | 15 ++++++++------ src/bin/minedmap/tile_renderer.rs | 4 ++-- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 8d64171..ee870d0 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -30,26 +30,28 @@ pub type ProcessedRegion = ChunkArray>; pub struct Config { pub region_dir: PathBuf, pub processed_dir: PathBuf, - pub light_dir: PathBuf, - pub map_dir: PathBuf, + pub output_dir: PathBuf, } fn coord_filename(coords: TileCoords, ext: &str) -> String { format!("r.{}.{}.{}", coords.x, coords.z, ext) } +#[derive(Debug, Clone, Copy)] +pub enum TileKind { + Map, + Lightmap, +} + impl Config { pub fn new(args: super::Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); - let light_dir = [&args.output_dir, Path::new("light/0")].iter().collect(); - let map_dir = [&args.output_dir, Path::new("map/0")].iter().collect(); Config { region_dir, processed_dir, - light_dir, - map_dir, + output_dir: args.output_dir, } } @@ -58,14 +60,19 @@ impl Config { [&self.processed_dir, Path::new(&filename)].iter().collect() } - pub fn light_path(&self, coords: TileCoords) -> PathBuf { - let filename = coord_filename(coords, "png"); - [&self.light_dir, Path::new(&filename)].iter().collect() + pub fn tile_dir(&self, kind: TileKind, level: usize) -> PathBuf { + let prefix = match kind { + TileKind::Map => "map", + TileKind::Lightmap => "light", + }; + let dir = format!("{}/{}", prefix, level); + [&self.output_dir, Path::new(&dir)].iter().collect() } - pub fn map_path(&self, coords: TileCoords) -> PathBuf { + pub fn tile_path(&self, kind: TileKind, level: usize, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "png"); - [&self.map_dir, Path::new(&filename)].iter().collect() + let dir = self.tile_dir(kind, level); + [Path::new(&dir), Path::new(&filename)].iter().collect() } } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 661c92a..c5d2a7c 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -71,11 +71,14 @@ impl<'a> RegionProcessor<'a> { } fn save_lightmap(&self, coords: TileCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { - fs::create_with_tmpfile(&self.config.light_path(coords), |file| { - lightmap - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }) + fs::create_with_tmpfile( + &self.config.tile_path(TileKind::Lightmap, 0, coords), + |file| { + lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }, + ) } /// Processes a single region file @@ -126,7 +129,7 @@ impl<'a> RegionProcessor<'a> { })?; fs::create_dir_all(&self.config.processed_dir)?; - fs::create_dir_all(&self.config.light_dir)?; + fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; let mut ret = BTreeSet::new(); diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 02376c7..bdd8113 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -59,7 +59,7 @@ impl<'a> TileRenderer<'a> { fn render_tile(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - let output_path = self.config.map_path(coords); + let output_path = self.config.tile_path(TileKind::Map, 0, coords); println!( "Rendering tile {}", @@ -81,7 +81,7 @@ impl<'a> TileRenderer<'a> { } pub fn run(self, regions: impl IntoIterator) -> Result<()> { - fs::create_dir_all(&self.config.map_dir)?; + fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; for coords in regions { if let Err(err) = self.render_tile(coords) { From 86382772c35766f8d01447f58f0ae3251e4114bf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 19:45:40 +0200 Subject: [PATCH 183/460] minedmap/tile_renderer: print tile path relative to output directory We will use strings of the same format for mipmap tile paths. --- src/bin/minedmap/tile_renderer.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index bdd8113..ee79883 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -64,9 +64,9 @@ impl<'a> TileRenderer<'a> { println!( "Rendering tile {}", output_path - .file_name() - .unwrap_or_default() - .to_string_lossy(), + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), ); let region = self.load_region(coords)?; @@ -85,7 +85,7 @@ impl<'a> TileRenderer<'a> { for coords in regions { if let Err(err) = self.render_tile(coords) { - eprintln!("Failed to render tile {:?}: {:?}", coords, err,); + eprintln!("Failed to render tile {:?}: {:?}", coords, err); } } From 216aa6ceec07eeb095767511258eacc1922f0757 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 21:32:40 +0200 Subject: [PATCH 184/460] minedmap: add mipmapping --- src/bin/minedmap/main.rs | 3 + src/bin/minedmap/tile_mipmapper.rs | 125 +++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/bin/minedmap/tile_mipmapper.rs diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 3aef0f8..22fed56 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -1,5 +1,6 @@ mod common; mod region_processor; +mod tile_mipmapper; mod tile_renderer; use std::path::PathBuf; @@ -9,6 +10,7 @@ use clap::Parser; use common::Config; use region_processor::RegionProcessor; +use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; #[derive(Debug, Parser)] @@ -25,6 +27,7 @@ fn main() -> Result<()> { let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config).run(regions.iter().copied())?; + TileMipmapper::new(&config).run(regions)?; Ok(()) } diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs new file mode 100644 index 0000000..567c656 --- /dev/null +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -0,0 +1,125 @@ +use std::collections::BTreeSet; + +use anyhow::{Context, Result}; + +use minedmap::{io::fs, types::*}; + +use super::common::*; + +pub struct TileMipmapper<'a> { + config: &'a Config, +} + +impl<'a> TileMipmapper<'a> { + pub fn new(config: &'a Config) -> Self { + TileMipmapper { config } + } + + fn done(tiles: &BTreeSet) -> bool { + tiles + .into_iter() + .all(|TileCoords { x, z }| (-1..=0).contains(x) && (-1..=0).contains(z)) + } + + fn map_coords(tiles: &BTreeSet) -> BTreeSet { + let mut ret = BTreeSet::new(); + + for coords in tiles { + ret.insert(TileCoords { + x: coords.x >> 1, + z: coords.z >> 1, + }); + } + + ret + } + + fn render_mipmap( + &self, + kind: TileKind, + level: usize, + coords: TileCoords, + prev: &BTreeSet, + ) -> Result<()> + where + [P::Subpixel]: image::EncodableLayout, + image::ImageBuffer>: Into, + { + const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + + let output_path = self.config.tile_path(kind, level, coords); + + println!( + "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) in [(0, 0), (0, 1), (1, 0), (1, 1)] { + let source_coords = TileCoords { + x: 2 * coords.x + dx, + z: 2 * coords.z + dz, + }; + if !prev.contains(&source_coords) { + continue; + } + + let source_path = self.config.tile_path(kind, level - 1, source_coords); + let source = match image::open(&source_path) { + Ok(source) => source, + Err(err) => { + eprintln!( + "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_tmpfile(&output_path, |file| { + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) + } + + pub fn run(self, tiles: BTreeSet) -> Result>> { + let mut tile_stack = vec![tiles]; + + loop { + let level = tile_stack.len(); + let prev = &tile_stack[level - 1]; + if Self::done(prev) { + break; + } + + 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); + + for &coords in &next { + self.render_mipmap::>(TileKind::Map, level, coords, prev)?; + self.render_mipmap::>(TileKind::Lightmap, level, coords, prev)?; + } + + tile_stack.push(next); + } + + Ok(tile_stack) + } +} From b63a18ad6fbaca09705012f046d59c74b7ca1858 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 22:15:25 +0200 Subject: [PATCH 185/460] tile_mipmapper: store tile coordinates in nested map/set Use the same data structure as the frontend. --- src/bin/minedmap/common.rs | 14 ++++++++ src/bin/minedmap/tile_mipmapper.rs | 53 ++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index ee870d0..7062d45 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -1,4 +1,5 @@ use std::{ + collections::{BTreeMap, BTreeSet}, fmt::Debug, path::{Path, PathBuf}, }; @@ -19,6 +20,19 @@ impl Debug for TileCoords { } } +#[derive(Debug, Clone, Default)] +pub struct TileCoordMap(pub BTreeMap>); + +impl TileCoordMap { + pub fn contains(&self, coords: TileCoords) -> bool { + let Some(xs) = self.0.get(&coords.z) else { + return false; + }; + + xs.contains(&coords.x) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProcessedChunk { pub blocks: Box, diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 567c656..8e1415e 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -15,20 +15,23 @@ impl<'a> TileMipmapper<'a> { TileMipmapper { config } } - fn done(tiles: &BTreeSet) -> bool { + fn done(tiles: &TileCoordMap) -> bool { tiles - .into_iter() - .all(|TileCoords { x, z }| (-1..=0).contains(x) && (-1..=0).contains(z)) + .0 + .iter() + .all(|(z, xs)| (-1..=0).contains(z) && xs.iter().all(|x| (-1..=0).contains(x))) } - fn map_coords(tiles: &BTreeSet) -> BTreeSet { - let mut ret = BTreeSet::new(); + fn map_coords(tiles: &TileCoordMap) -> TileCoordMap { + let mut ret = TileCoordMap::default(); - for coords in tiles { - ret.insert(TileCoords { - x: coords.x >> 1, - z: coords.z >> 1, - }); + 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 @@ -39,7 +42,7 @@ impl<'a> TileMipmapper<'a> { kind: TileKind, level: usize, coords: TileCoords, - prev: &BTreeSet, + prev: &TileCoordMap, ) -> Result<()> where [P::Subpixel]: image::EncodableLayout, @@ -65,7 +68,7 @@ impl<'a> TileMipmapper<'a> { x: 2 * coords.x + dx, z: 2 * coords.z + dz, }; - if !prev.contains(&source_coords) { + if !prev.contains(source_coords) { continue; } @@ -97,8 +100,16 @@ impl<'a> TileMipmapper<'a> { }) } - pub fn run(self, tiles: BTreeSet) -> Result>> { - let mut tile_stack = vec![tiles]; + pub fn run(self, tiles: BTreeSet) -> Result> { + let mut tile_stack = { + let mut tile_map = TileCoordMap::default(); + + for TileCoords { x, z } in tiles { + tile_map.0.entry(z).or_default().insert(x); + } + + vec![tile_map] + }; loop { let level = tile_stack.len(); @@ -112,9 +123,17 @@ impl<'a> TileMipmapper<'a> { let next = Self::map_coords(prev); - for &coords in &next { - self.render_mipmap::>(TileKind::Map, level, coords, prev)?; - self.render_mipmap::>(TileKind::Lightmap, level, coords, prev)?; + for (&z, xs) in &next.0 { + for &x in xs { + let coords = TileCoords { x, z }; + self.render_mipmap::>(TileKind::Map, level, coords, prev)?; + self.render_mipmap::>( + TileKind::Lightmap, + level, + coords, + prev, + )?; + } } tile_stack.push(next); From f9fc9efe8d58b045b8305cf161dde4577c321c1d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 22:19:35 +0200 Subject: [PATCH 186/460] Revert "minedmap: store region list in BTreeSet" This reverts commit b53d34da3d0eae697491b7e4ffc40b828b9b0b9a. With the change of the mipmapper data structure, we need a conversion step anyways, so we can keep using the Vec before mipmapping. --- src/bin/minedmap/main.rs | 4 ++-- src/bin/minedmap/region_processor.rs | 8 ++++---- src/bin/minedmap/tile_mipmapper.rs | 6 ++---- src/bin/minedmap/tile_renderer.rs | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 22fed56..5e89025 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -26,8 +26,8 @@ fn main() -> Result<()> { let config = Config::new(args); let regions = RegionProcessor::new(&config).run()?; - TileRenderer::new(&config).run(regions.iter().copied())?; - TileMipmapper::new(&config).run(regions)?; + TileRenderer::new(&config).run(®ions)?; + TileMipmapper::new(&config).run(®ions)?; Ok(()) } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index c5d2a7c..854c506 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeSet, path::Path}; +use std::path::Path; use anyhow::{Context, Result}; @@ -120,7 +120,7 @@ impl<'a> RegionProcessor<'a> { /// Iterates over all region files of a Minecraft save directory /// /// Returns a list of the coordinates of all processed regions - pub fn run(self) -> Result> { + pub fn run(self) -> Result> { let read_dir = self.config.region_dir.read_dir().with_context(|| { format!( "Failed to read directory {}", @@ -131,7 +131,7 @@ impl<'a> RegionProcessor<'a> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; - let mut ret = BTreeSet::new(); + let mut ret = Vec::new(); for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { // We are only interested in regular files @@ -153,7 +153,7 @@ impl<'a> RegionProcessor<'a> { ); } - ret.insert(coords); + ret.push(coords); } Ok(ret) diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 8e1415e..f24a41e 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeSet; - use anyhow::{Context, Result}; use minedmap::{io::fs, types::*}; @@ -100,11 +98,11 @@ impl<'a> TileMipmapper<'a> { }) } - pub fn run(self, tiles: BTreeSet) -> Result> { + pub fn run(self, tiles: &[TileCoords]) -> Result> { let mut tile_stack = { let mut tile_map = TileCoordMap::default(); - for TileCoords { x, z } in tiles { + for &TileCoords { x, z } in tiles { tile_map.0.entry(z).or_default().insert(x); } diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index ee79883..2956081 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -80,10 +80,10 @@ impl<'a> TileRenderer<'a> { }) } - pub fn run(self, regions: impl IntoIterator) -> Result<()> { + pub fn run(self, regions: &[TileCoords]) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; - for coords in regions { + for &coords in regions { if let Err(err) = self.render_tile(coords) { eprintln!("Failed to render tile {:?}: {:?}", coords, err); } From 429b7888f62f747e5393f50c6e7e5f825c29dd2a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 23:08:43 +0200 Subject: [PATCH 187/460] world/de: add level.dat data structures We only need the spawn point from level.dat. --- src/world/de.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/world/de.rs b/src/world/de.rs index 844bd29..82aa11c 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -99,3 +99,18 @@ pub struct Chunk { #[serde(flatten)] pub chunk: ChunkVariants, } + +/// "Data" compound element of level.dat +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct LevelDatData { + pub spawn_x: i32, + pub spawn_z: i32, +} + +/// Toplevel compound element of level.dat +#[derive(Debug, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct LevelDat { + pub data: LevelDatData, +} From 757f6ff16665b20574e35c440240826a76aa9ee0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 2 Jul 2023 23:09:14 +0200 Subject: [PATCH 188/460] minedmap: write info.json file with tilemap metadata With this change, the new minedmap implementation can generate all necessary data for the frontend to work. --- Cargo.lock | 24 +++++++ Cargo.toml | 1 + src/bin/minedmap/common.rs | 9 ++- src/bin/minedmap/main.rs | 5 +- src/bin/minedmap/metadata_writer.rs | 106 ++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/bin/minedmap/metadata_writer.rs diff --git a/Cargo.lock b/Cargo.lock index d8fac2f..a0b4d5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,6 +325,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "jobserver" version = "0.1.26" @@ -372,6 +378,7 @@ dependencies = [ "itertools", "num-integer", "serde", + "serde_json", "zstd", ] @@ -471,6 +478,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + [[package]] name = "serde" version = "1.0.164" @@ -500,6 +513,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "simd-adler32" version = "0.3.5" diff --git a/Cargo.toml b/Cargo.toml index 60a20cc..5e04100 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] } itertools = "0.11.0" num-integer = "0.1.45" serde = "1.0.152" +serde_json = "1.0.99" zstd = "0.12.3" [features] diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 7062d45..4aed1c0 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -20,7 +20,8 @@ impl Debug for TileCoords { } } -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Serialize)] +#[serde(transparent)] pub struct TileCoordMap(pub BTreeMap>); impl TileCoordMap { @@ -45,6 +46,8 @@ pub struct Config { pub region_dir: PathBuf, pub processed_dir: PathBuf, pub output_dir: PathBuf, + pub level_dat_path: PathBuf, + pub metadata_path: PathBuf, } fn coord_filename(coords: TileCoords, ext: &str) -> String { @@ -61,11 +64,15 @@ impl Config { pub fn new(args: super::Args) -> Self { let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); + let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); + let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); Config { region_dir, processed_dir, output_dir: args.output_dir, + level_dat_path, + metadata_path, } } diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 5e89025..34aa985 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -1,4 +1,5 @@ mod common; +mod metadata_writer; mod region_processor; mod tile_mipmapper; mod tile_renderer; @@ -9,6 +10,7 @@ use anyhow::Result; use clap::Parser; use common::Config; +use metadata_writer::MetadataWriter; use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; @@ -27,7 +29,8 @@ fn main() -> Result<()> { let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config).run(®ions)?; - TileMipmapper::new(&config).run(®ions)?; + let tiles = TileMipmapper::new(&config).run(®ions)?; + MetadataWriter::new(&config).run(tiles)?; Ok(()) } diff --git a/src/bin/minedmap/metadata_writer.rs b/src/bin/minedmap/metadata_writer.rs new file mode 100644 index 0000000..437152a --- /dev/null +++ b/src/bin/minedmap/metadata_writer.rs @@ -0,0 +1,106 @@ +use anyhow::{Context, Result}; +use minedmap::{io::fs, world::de}; +use serde::Serialize; + +use super::common::*; + +pub struct MetadataWriter<'a> { + config: &'a Config, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct Bounds { + min_x: i32, + max_x: i32, + min_z: i32, + max_z: i32, +} + +#[derive(Debug, Serialize)] +struct Mipmap<'t> { + bounds: Bounds, + regions: &'t TileCoordMap, +} + +#[derive(Debug, Serialize)] +struct Spawn { + x: i32, + z: i32, +} + +#[derive(Debug, Serialize)] +struct Metadata<'t> { + mipmaps: Vec>, + spawn: Spawn, +} + +impl<'a> MetadataWriter<'a> { + pub fn new(config: &'a Config) -> Self { + MetadataWriter { config } + } + + fn mipmap_entry(regions: &TileCoordMap) -> Mipmap { + let mut min_x = i32::MAX; + let mut max_x = i32::MIN; + let mut min_z = i32::MAX; + let mut max_z = i32::MIN; + + for (&z, xs) in ®ions.0 { + if z < min_z { + min_z = z; + } + if z > max_z { + max_z = z; + } + + for &x in xs { + if x < min_x { + min_x = x; + } + if x > max_x { + max_x = x; + } + } + } + + Mipmap { + bounds: Bounds { + min_x, + max_x, + min_z, + max_z, + }, + regions, + } + } + + fn read_level_dat(&self) -> Result { + minedmap::io::data::from_file(&self.config.level_dat_path) + .context("Failed to read level.dat") + } + + fn spawn(level_dat: &de::LevelDat) -> Spawn { + Spawn { + x: level_dat.data.spawn_x, + z: level_dat.data.spawn_z, + } + } + + pub fn run(&self, tiles: Vec) -> Result<()> { + let level_dat = self.read_level_dat()?; + + let mut metadata = Metadata { + mipmaps: Vec::new(), + spawn: Self::spawn(&level_dat), + }; + + for tile_map in tiles.iter() { + 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") + }) + } +} From 99c4de0b07c3bb9eafbf1810a7ca3c9670fa67fd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 3 Jul 2023 23:27:59 +0200 Subject: [PATCH 189/460] Update dependencies --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0b4d5b..3cf1afc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "jobserver" @@ -467,9 +467,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.1" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3" +checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" dependencies = [ "bitflags 2.3.3", "errno", @@ -480,33 +480,33 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "f3c5113243e4a3a1c96587342d067f3e6b0f50790b6cf40d2868eb647a3eef0e" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" dependencies = [ "proc-macro2", "quote", @@ -538,9 +538,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.22" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -549,9 +549,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "utf8parse" From c471f84573a573b46db76e7a018eec2e9a6deaac Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 3 Jul 2023 23:45:00 +0200 Subject: [PATCH 190/460] resource/block_color: fix scaling of biome-specific colors All biome-specific colors (water/foliage/grass) were too bright by a factor of 255 (i.e., white). --- src/resource/block_color.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index 21cd5c7..3cb8e22 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -2,10 +2,14 @@ use super::{Biome, BlockType, Color}; use glam::Vec3; -fn color_vec(color: Color) -> Vec3 { +fn color_vec_unscaled(color: Color) -> Vec3 { Vec3::from_array(color.0.map(f32::from)) } +fn color_vec(color: Color) -> Vec3 { + color_vec_unscaled(color) / 255.0 +} + fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { let temp = (biome.temp() - f32::max((depth - 64.0) / 600.0, 0.0)).clamp(0.0, 1.0); let downfall = biome.downfall().clamp(0.0, 1.0) * temp; @@ -71,7 +75,7 @@ const EVERGREEN_COLOR: Vec3 = Vec3::new(0.380, 0.600, 0.380); // == color_vec(Co pub fn block_color(block: BlockType, biome: &Biome, depth: f32) -> [u8; 4] { use super::BlockFlag::*; - let mut color = color_vec(block.color); + let mut color = color_vec_unscaled(block.color); if block.is(Grass) { color *= biome.grass_color(depth); From d84e2ca49d7200b04f00c24f06799e8cabcaf1cf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 3 Jul 2023 23:49:36 +0200 Subject: [PATCH 191/460] resource/block_color: fix default foliage colors The code accidentally used the grass colors. --- src/resource/block_color.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index 3cb8e22..23bd61e 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -40,9 +40,9 @@ impl BiomeExt for Biome { use super::BiomeGrassColorModifier::*; const FOLIAGE_COLORS: [Vec3; 3] = [ - Vec3::new(0.502, 0.706, 0.592), // lower right - Vec3::new(0.247, 0.012, -0.259), // lower left - lower right - Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left + Vec3::new(0.376, 0.631, 0.482), // lower right + Vec3::new(0.306, 0.012, -0.317), // lower left - lower right + Vec3::new(-0.580, 0.106, -0.165), // upper left - lower left ]; const DARK_FOREST_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) const SWAMP_FOLIAGE_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) From c472b61ef7bcd6e2a27313bf724281058b4ffa3d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 4 Jul 2023 00:21:27 +0200 Subject: [PATCH 192/460] resource/block_color: actually apply grass color modifiers to grass Apply the modifiers to grass, not to foliage. --- src/resource/block_color.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index 23bd61e..c239d96 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -25,39 +25,39 @@ trait BiomeExt { impl BiomeExt for Biome { fn grass_color(&self, depth: f32) -> Vec3 { + use super::BiomeGrassColorModifier::*; + const GRASS_COLORS: [Vec3; 3] = [ Vec3::new(0.502, 0.706, 0.592), // lower right Vec3::new(0.247, 0.012, -0.259), // lower left - lower right Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left ]; + const DARK_FOREST_GRASS_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) + const SWAMP_GRASS_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) - self.grass_color - .map(color_vec) - .unwrap_or_else(|| color_from_params(&GRASS_COLORS, self, depth)) + let regular_color = || { + self.grass_color + .map(color_vec) + .unwrap_or_else(|| color_from_params(&GRASS_COLORS, self, depth)) + }; + + match self.grass_color_modifier { + Some(DarkForest) => 0.5 * (regular_color() + DARK_FOREST_GRASS_COLOR), + Some(Swamp) => SWAMP_GRASS_COLOR, + None => regular_color(), + } } fn foliage_color(&self, depth: f32) -> Vec3 { - use super::BiomeGrassColorModifier::*; - const FOLIAGE_COLORS: [Vec3; 3] = [ Vec3::new(0.376, 0.631, 0.482), // lower right Vec3::new(0.306, 0.012, -0.317), // lower left - lower right Vec3::new(-0.580, 0.106, -0.165), // upper left - lower left ]; - const DARK_FOREST_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) - const SWAMP_FOLIAGE_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) - let regular_color = || { - self.foliage_color - .map(color_vec) - .unwrap_or_else(|| color_from_params(&FOLIAGE_COLORS, self, depth)) - }; - - match self.grass_color_modifier { - Some(DarkForest) => 0.5 * (regular_color() + DARK_FOREST_COLOR), - Some(Swamp) => SWAMP_FOLIAGE_COLOR, - None => regular_color(), - } + self.foliage_color + .map(color_vec) + .unwrap_or_else(|| color_from_params(&FOLIAGE_COLORS, self, depth)) } fn water_color(&self) -> Vec3 { From cb791f48e91e99b703d5ac383ccb5d0b416ee94f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Jul 2023 20:03:23 +0200 Subject: [PATCH 193/460] Update dependencies --- Cargo.lock | 96 +++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cf1afc..b286664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "autocfg" @@ -125,9 +125,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.10" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.10" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -196,9 +196,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "enumflags2" @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -287,9 +287,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "image" @@ -307,9 +307,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix", @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" @@ -348,9 +348,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libz-ng-sys" -version = "1.1.9" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468756f34903b582fe7154dc1ffdebd89d0562c4a43b53c621bb0f1b1043ccb" +checksum = "3dd9f43e75536a46ee0f92b758f6b63846e594e86638c61a9251338a65baea63" dependencies = [ "cmake", "libc", @@ -415,9 +415,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -449,27 +449,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] [[package]] name = "rustix" -version = "0.38.2" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ "bitflags 2.3.3", "errno", @@ -480,33 +480,33 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.166" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c5113243e4a3a1c96587342d067f3e6b0f50790b6cf40d2868eb647a3eef0e" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" dependencies = [ "proc-macro2", "quote", @@ -515,9 +515,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -526,9 +526,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "strsim" @@ -538,9 +538,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.23" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -549,9 +549,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "utf8parse" @@ -627,18 +627,18 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "zstd" -version = "0.12.3+zstd.1.5.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.5+zstd.1.5.4" +version = "6.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" dependencies = [ "libc", "zstd-sys", From e18d4cea824e5b5a820b137eea65d57898283d22 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Jul 2023 20:31:40 +0200 Subject: [PATCH 194/460] io/fs: do not replace files with unchanged contents Do not update file timestamps when contents have not actually changed. --- src/io/fs.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/io/fs.rs b/src/io/fs.rs index 46e8726..2109961 100644 --- a/src/io/fs.rs +++ b/src/io/fs.rs @@ -1,6 +1,6 @@ use std::{ fs::{self, File}, - io::{BufWriter, Write}, + io::{BufReader, BufWriter, Read, Write}, path::{Path, PathBuf}, }; @@ -41,19 +41,44 @@ where .with_context(|| format!("Failed to write file {}", path.display())) } +pub fn equal(path1: &Path, path2: &Path) -> Result { + let mut file1 = BufReader::new( + fs::File::open(path1) + .with_context(|| format!("Failed to open file {}", path1.display()))?, + ) + .bytes(); + let mut file2 = BufReader::new( + fs::File::open(path2) + .with_context(|| format!("Failed to open file {}", path2.display()))?, + ) + .bytes(); + + Ok(loop { + match (file1.next().transpose()?, file2.next().transpose()?) { + (Some(b1), Some(b2)) if b1 == b2 => continue, + (None, None) => break true, + _ => break false, + }; + }) +} + pub fn create_with_tmpfile(path: &Path, f: F) -> Result where F: FnOnce(&mut BufWriter) -> Result, { let tmp_path = tmpfile_name(path); + let mut cleanup = true; let ret = (|| { let ret = create(&tmp_path, f)?; - rename(&tmp_path, path)?; + if !matches!(equal(path, &tmp_path), Result::Ok(true)) { + rename(&tmp_path, path)?; + cleanup = false; + } Ok(ret) })(); - if ret.is_err() { + if cleanup { let _ = fs::remove_file(&tmp_path); } From 628a702fd74cae06aa53aa480a6bae5e4a716360 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Jul 2023 21:19:24 +0200 Subject: [PATCH 195/460] Store source modified timestamp with processed, lightmap and map tiles Allows to check whether the source is newer than the last update of the output files. --- src/bin/minedmap/region_processor.rs | 27 ++++++++++++----- src/bin/minedmap/tile_renderer.rs | 13 +++++--- src/io/fs.rs | 45 ++++++++++++++++++++++++++-- src/io/storage.rs | 5 ++-- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 854c506..2081785 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::{path::Path, time::SystemTime}; use anyhow::{Context, Result}; @@ -65,14 +65,25 @@ impl<'a> RegionProcessor<'a> { }) } - fn save_region(&self, coords: TileCoords, processed_region: &ProcessedRegion) -> Result<()> { + fn save_region( + &self, + coords: TileCoords, + processed_region: &ProcessedRegion, + timestamp: SystemTime, + ) -> Result<()> { let output_path = self.config.processed_path(coords); - storage::write(&output_path, processed_region) + storage::write(&output_path, processed_region, timestamp) } - fn save_lightmap(&self, coords: TileCoords, lightmap: &image::GrayAlphaImage) -> Result<()> { - fs::create_with_tmpfile( + fn save_lightmap( + &self, + coords: TileCoords, + lightmap: &image::GrayAlphaImage, + timestamp: SystemTime, + ) -> Result<()> { + fs::create_with_timestamp( &self.config.tile_path(TileKind::Lightmap, 0, coords), + timestamp, |file| { lightmap .write_to(file, image::ImageFormat::Png) @@ -90,6 +101,8 @@ impl<'a> RegionProcessor<'a> { let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); + let timestamp = fs::modified_timestamp(path)?; + minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData{ blocks, biomes, block_light, depths }) = self @@ -111,8 +124,8 @@ impl<'a> RegionProcessor<'a> { }, )?; - self.save_region(coords, &processed_region)?; - self.save_lightmap(coords, &lightmap)?; + self.save_region(coords, &processed_region, timestamp)?; + self.save_lightmap(coords, &lightmap, timestamp)?; Ok(()) } diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 2956081..0b804c8 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,3 +1,5 @@ +use std::time::SystemTime; + use anyhow::{Context, Result}; use minedmap::{ @@ -17,9 +19,12 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } - fn load_region(&self, coords: TileCoords) -> Result { + fn load_region(&self, coords: TileCoords) -> Result<(ProcessedRegion, SystemTime)> { let processed_path = self.config.processed_path(coords); - storage::read(&processed_path).context("Failed to load processed region data") + let timestamp = fs::modified_timestamp(&processed_path)?; + let region = + storage::read(&processed_path).context("Failed to load processed region data")?; + Ok((region, timestamp)) } fn render_chunk(image: &mut image::RgbaImage, coords: ChunkCoords, chunk: &ProcessedChunk) { @@ -69,11 +74,11 @@ impl<'a> TileRenderer<'a> { .display(), ); - let region = self.load_region(coords)?; + let (region, timestamp) = self.load_region(coords)?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion); - fs::create_with_tmpfile(&output_path, |file| { + fs::create_with_timestamp(&output_path, timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") diff --git a/src/io/fs.rs b/src/io/fs.rs index 2109961..0cb2a4d 100644 --- a/src/io/fs.rs +++ b/src/io/fs.rs @@ -2,19 +2,34 @@ use std::{ fs::{self, File}, io::{BufReader, BufWriter, Read, Write}, path::{Path, PathBuf}, + time::SystemTime, }; use anyhow::{Context, Ok, Result}; +use serde::Serialize; -fn tmpfile_name(path: &Path) -> PathBuf { +#[derive(Debug, Serialize)] +struct FileMeta { + timestamp: SystemTime, +} + +fn suffix_name(path: &Path, suffix: &str) -> PathBuf { let mut file_name = path.file_name().unwrap_or_default().to_os_string(); - file_name.push(".tmp"); + file_name.push(suffix); let mut ret = path.to_path_buf(); ret.set_file_name(file_name); ret } +fn tmpfile_name(path: &Path) -> PathBuf { + suffix_name(path, ".tmp") +} + +fn metafile_name(path: &Path) -> PathBuf { + suffix_name(path, ".meta") +} + pub fn create_dir_all(path: &Path) -> Result<()> { fs::create_dir_all(path) .with_context(|| format!("Failed to create directory {}", path.display(),)) @@ -84,3 +99,29 @@ where ret } + +pub fn modified_timestamp(path: &Path) -> Result { + fs::metadata(path) + .and_then(|meta| meta.modified()) + .with_context(|| { + format!( + "Failed to get modified timestamp of file {}", + path.display() + ) + }) +} + +pub fn create_with_timestamp(path: &Path, timestamp: SystemTime, f: F) -> Result +where + F: FnOnce(&mut BufWriter) -> Result, +{ + let ret = create_with_tmpfile(path, f)?; + + let meta_path = metafile_name(path); + create(&meta_path, |file| { + serde_json::to_writer(file, &FileMeta { timestamp })?; + Ok(()) + })?; + + Ok(ret) +} diff --git a/src/io/storage.rs b/src/io/storage.rs index c1a9e5e..b889231 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -2,6 +2,7 @@ use std::{ fs::File, io::{Read, Write}, path::Path, + time::SystemTime, }; use anyhow::{Context, Result}; @@ -9,8 +10,8 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; -pub fn write(path: &Path, value: &T) -> Result<()> { - fs::create_with_tmpfile(path, |file| { +pub fn write(path: &Path, value: &T, timestamp: SystemTime) -> Result<()> { + fs::create_with_timestamp(path, timestamp, |file| { let data = bincode::serialize(value)?; let len = u32::try_from(data.len())?; let compressed = zstd::bulk::compress(&data, 1)?; From 4d6644f42772d0164e640c29d18f769c94c883ef Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Jul 2023 21:38:42 +0200 Subject: [PATCH 196/460] minedmap/tile_mipmapper: store source modified timestamp with mipmapped tiles --- src/bin/minedmap/tile_mipmapper.rs | 38 ++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index f24a41e..51eebd9 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -61,16 +61,34 @@ impl<'a> TileMipmapper<'a> { let mut image: image::DynamicImage = image::ImageBuffer::>::new(N, N).into(); - for (dx, dz) in [(0, 0), (0, 1), (1, 0), (1, 1)] { - let source_coords = TileCoords { - x: 2 * coords.x + dx, - z: 2 * coords.z + dz, - }; - if !prev.contains(source_coords) { - continue; - } + 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 source_path = self.config.tile_path(kind, level - 1, source_coords); + let timestamp = match fs::modified_timestamp(&source_path) { + Ok(timestamp) => timestamp, + Err(err) => { + eprintln!("{}", err); + return None; + } + }; + Some(((dx, dz), source_path, timestamp)) + }) + .collect(); + + let Some(timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { + return Ok(()); + }; + + for ((dx, dz), source_path, _) in sources { let source = match image::open(&source_path) { Ok(source) => source, Err(err) => { @@ -91,7 +109,7 @@ impl<'a> TileMipmapper<'a> { ); } - fs::create_with_tmpfile(&output_path, |file| { + fs::create_with_timestamp(&output_path, timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") From 60771382920b9178ef60d0f20c3c898a52f274de Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 30 Jul 2023 21:48:58 +0200 Subject: [PATCH 197/460] Add version field to file metadata --- src/bin/minedmap/common.rs | 5 ++++- src/bin/minedmap/region_processor.rs | 3 ++- src/bin/minedmap/tile_mipmapper.rs | 2 +- src/bin/minedmap/tile_renderer.rs | 2 +- src/io/fs.rs | 13 +++++++++++-- src/io/storage.rs | 9 +++++++-- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 4aed1c0..a108e8d 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -6,7 +6,10 @@ use std::{ use serde::{Deserialize, Serialize}; -use minedmap::{types::*, world::layer}; +use minedmap::{io::fs::FileMetaVersion, types::*, world::layer}; + +// Increase to force regeneration of all output files +pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct TileCoords { diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 2081785..d20f82b 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -72,7 +72,7 @@ impl<'a> RegionProcessor<'a> { timestamp: SystemTime, ) -> Result<()> { let output_path = self.config.processed_path(coords); - storage::write(&output_path, processed_region, timestamp) + storage::write(&output_path, processed_region, FILE_META_VERSION, timestamp) } fn save_lightmap( @@ -83,6 +83,7 @@ impl<'a> RegionProcessor<'a> { ) -> Result<()> { fs::create_with_timestamp( &self.config.tile_path(TileKind::Lightmap, 0, coords), + FILE_META_VERSION, timestamp, |file| { lightmap diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 51eebd9..22b942d 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -109,7 +109,7 @@ impl<'a> TileMipmapper<'a> { ); } - fs::create_with_timestamp(&output_path, timestamp, |file| { + fs::create_with_timestamp(&output_path, FILE_META_VERSION, timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 0b804c8..0e91054 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -78,7 +78,7 @@ impl<'a> TileRenderer<'a> { let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion); - fs::create_with_timestamp(&output_path, timestamp, |file| { + fs::create_with_timestamp(&output_path, FILE_META_VERSION, timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") diff --git a/src/io/fs.rs b/src/io/fs.rs index 0cb2a4d..dfb2e78 100644 --- a/src/io/fs.rs +++ b/src/io/fs.rs @@ -8,8 +8,12 @@ use std::{ use anyhow::{Context, Ok, Result}; use serde::Serialize; +#[derive(Debug, Clone, Copy, Serialize)] +pub struct FileMetaVersion(pub u32); + #[derive(Debug, Serialize)] struct FileMeta { + version: FileMetaVersion, timestamp: SystemTime, } @@ -111,7 +115,12 @@ pub fn modified_timestamp(path: &Path) -> Result { }) } -pub fn create_with_timestamp(path: &Path, timestamp: SystemTime, f: F) -> Result +pub fn create_with_timestamp( + path: &Path, + version: FileMetaVersion, + timestamp: SystemTime, + f: F, +) -> Result where F: FnOnce(&mut BufWriter) -> Result, { @@ -119,7 +128,7 @@ where let meta_path = metafile_name(path); create(&meta_path, |file| { - serde_json::to_writer(file, &FileMeta { timestamp })?; + serde_json::to_writer(file, &FileMeta { version, timestamp })?; Ok(()) })?; diff --git a/src/io/storage.rs b/src/io/storage.rs index b889231..4ba6050 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -10,8 +10,13 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; -pub fn write(path: &Path, value: &T, timestamp: SystemTime) -> Result<()> { - fs::create_with_timestamp(path, timestamp, |file| { +pub fn write( + 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)?; From 80781c9c203aae666846cbdd1aa4a39c6191dacb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 31 Jul 2023 00:23:06 +0200 Subject: [PATCH 198/460] minedmap: skip generation steps when the inputs are unchanged --- src/bin/minedmap/region_processor.rs | 49 ++++++++++++++++------------ src/bin/minedmap/tile_mipmapper.rs | 38 +++++++++++++-------- src/bin/minedmap/tile_renderer.rs | 42 ++++++++++++++++-------- src/io/fs.rs | 18 ++++++++-- 4 files changed, 97 insertions(+), 50 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index d20f82b..a95f6ea 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -66,43 +66,46 @@ impl<'a> RegionProcessor<'a> { } fn save_region( - &self, - coords: TileCoords, + path: &Path, processed_region: &ProcessedRegion, timestamp: SystemTime, ) -> Result<()> { - let output_path = self.config.processed_path(coords); - storage::write(&output_path, processed_region, FILE_META_VERSION, timestamp) + storage::write(path, processed_region, FILE_META_VERSION, timestamp) } fn save_lightmap( - &self, - coords: TileCoords, + path: &Path, lightmap: &image::GrayAlphaImage, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp( - &self.config.tile_path(TileKind::Lightmap, 0, coords), - FILE_META_VERSION, - timestamp, - |file| { - lightmap - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }, - ) + fs::create_with_timestamp(path, FILE_META_VERSION, timestamp, |file| { + lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) } /// Processes a single region file fn process_region(&self, path: &Path, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - println!("Processing region r.{}.{}.mca", coords.x, coords.z); - let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); - let timestamp = fs::modified_timestamp(path)?; + let input_timestamp = fs::modified_timestamp(path)?; + + let output_path = self.config.processed_path(coords); + let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); + let lightmap_path = self.config.tile_path(TileKind::Lightmap, 0, coords); + let lightmap_timestamp = fs::read_timestamp(&lightmap_path, FILE_META_VERSION); + + if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp + { + println!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); + return Ok(()); + } + + println!("Processing region r.{}.{}.mca", coords.x, coords.z); minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { @@ -125,8 +128,12 @@ impl<'a> RegionProcessor<'a> { }, )?; - self.save_region(coords, &processed_region, timestamp)?; - self.save_lightmap(coords, &lightmap, timestamp)?; + if Some(input_timestamp) > output_timestamp { + Self::save_region(&output_path, &processed_region, input_timestamp)?; + } + if Some(input_timestamp) > lightmap_timestamp { + Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; + } Ok(()) } diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 22b942d..40add3a 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -49,17 +49,7 @@ impl<'a> TileMipmapper<'a> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let output_path = self.config.tile_path(kind, level, coords); - - println!( - "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(); + let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] .into_iter() @@ -84,10 +74,32 @@ impl<'a> TileMipmapper<'a> { }) .collect(); - let Some(timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { + let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { return Ok(()); }; + if Some(input_timestamp) <= output_timestamp { + println!( + "Skipping unchanged mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + return Ok(()); + } + + println!( + "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, @@ -109,7 +121,7 @@ impl<'a> TileMipmapper<'a> { ); } - fs::create_with_timestamp(&output_path, FILE_META_VERSION, timestamp, |file| { + fs::create_with_timestamp(&output_path, FILE_META_VERSION, input_timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 0e91054..955c964 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,4 +1,4 @@ -use std::time::SystemTime; +use std::path::Path; use anyhow::{Context, Result}; @@ -19,12 +19,8 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } - fn load_region(&self, coords: TileCoords) -> Result<(ProcessedRegion, SystemTime)> { - let processed_path = self.config.processed_path(coords); - let timestamp = fs::modified_timestamp(&processed_path)?; - let region = - storage::read(&processed_path).context("Failed to load processed region data")?; - Ok((region, timestamp)) + fn load_region(processed_path: &Path) -> Result { + storage::read(processed_path).context("Failed to load processed region data") } fn render_chunk(image: &mut image::RgbaImage, coords: ChunkCoords, chunk: &ProcessedChunk) { @@ -64,7 +60,22 @@ impl<'a> TileRenderer<'a> { fn render_tile(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; + let processed_path = self.config.processed_path(coords); + let processed_timestamp = fs::modified_timestamp(&processed_path)?; + let output_path = self.config.tile_path(TileKind::Map, 0, coords); + let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); + + if Some(processed_timestamp) <= output_timestamp { + println!( + "Skipping unchanged tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + return Ok(()); + } println!( "Rendering tile {}", @@ -74,15 +85,20 @@ impl<'a> TileRenderer<'a> { .display(), ); - let (region, timestamp) = self.load_region(coords)?; + let region = Self::load_region(&processed_path)?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion); - fs::create_with_timestamp(&output_path, FILE_META_VERSION, timestamp, |file| { - image - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }) + fs::create_with_timestamp( + &output_path, + FILE_META_VERSION, + processed_timestamp, + |file| { + image + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }, + ) } pub fn run(self, regions: &[TileCoords]) -> Result<()> { diff --git a/src/io/fs.rs b/src/io/fs.rs index dfb2e78..8f6a79a 100644 --- a/src/io/fs.rs +++ b/src/io/fs.rs @@ -6,12 +6,12 @@ use std::{ }; use anyhow::{Context, Ok, Result}; -use serde::Serialize; +use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Copy, Serialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub struct FileMetaVersion(pub u32); -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Deserialize)] struct FileMeta { version: FileMetaVersion, timestamp: SystemTime, @@ -115,6 +115,18 @@ pub fn modified_timestamp(path: &Path) -> Result { }) } +pub fn read_timestamp(path: &Path, version: FileMetaVersion) -> Option { + let meta_path = metafile_name(path); + let mut file = BufReader::new(fs::File::open(meta_path).ok()?); + + let meta: FileMeta = serde_json::from_reader(&mut file).ok()?; + if meta.version != version { + return None; + } + + Some(meta.timestamp) +} + pub fn create_with_timestamp( path: &Path, version: FileMetaVersion, From e39f48d8fed66cb811030f500ea8ae13f0e2bb4d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Aug 2023 00:14:37 +0200 Subject: [PATCH 199/460] types: use const generics for more generic coordinate types Enum support in const generics would be even nicer, but for now the integer generic is the best Rust can do. --- src/bin/minedmap/region_processor.rs | 4 +-- src/bin/minedmap/tile_renderer.rs | 4 +-- src/types.rs | 54 ++++++++++++++++++---------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index a95f6ea..f2720c7 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -57,8 +57,8 @@ impl<'a> RegionProcessor<'a> { image::GrayAlphaImage::from_fn(N, N, |x, z| { let v: f32 = block_light[LayerBlockCoords { - x: BlockX(x as u8), - z: BlockZ(z as u8), + x: BlockX::new(x), + z: BlockZ::new(z), }] .into(); image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 955c964..70b55de 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -28,8 +28,8 @@ impl<'a> TileRenderer<'a> { let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { let coords = LayerBlockCoords { - x: BlockX(x as u8), - z: BlockZ(z as u8), + x: BlockX::new(x), + z: BlockZ::new(z), }; image::Rgba( match ( diff --git a/src/types.rs b/src/types.rs index 18045bb..465dd2a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,38 +7,57 @@ use std::{ use itertools::iproduct; use serde::{Deserialize, Serialize}; -macro_rules! coord_impl { +pub mod axis { + pub const X: u8 = 0; + pub const Y: u8 = 1; + pub const Z: u8 = 2; +} + +macro_rules! coord_type { ($t:ident, $max:expr) => { - impl $t { + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub struct $t(pub u8); + + impl $t { + const MAX: usize = $max; + + /// Constructs a new value + /// + /// Will panic if the value is not in the valid range + pub fn new>(value: T) -> Self { + Self( + value + .try_into() + .ok() + .filter(|&v| (v as usize) < Self::MAX) + .expect("coordinate should be in the valid range"), + ) + } + /// Returns an iterator over all possible values of the type - pub fn iter() -> impl Iterator + pub fn iter() -> impl Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator + Clone + Debug { - (0..$max as u8).map($t) + (0..Self::MAX as u8).map($t) } } }; } pub const BLOCKS_PER_CHUNK: usize = 16; +coord_type!(BlockCoord, BLOCKS_PER_CHUNK); /// A block X coordinate relative to a chunk -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BlockX(pub u8); -coord_impl!(BlockX, BLOCKS_PER_CHUNK); +pub type BlockX = BlockCoord<{ axis::X }>; /// A block Y coordinate relative to a chunk section -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BlockY(pub u8); -coord_impl!(BlockY, BLOCKS_PER_CHUNK); +pub type BlockY = BlockCoord<{ axis::Y }>; /// A block Z coordinate relative to a chunk -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BlockZ(pub u8); -coord_impl!(BlockZ, BLOCKS_PER_CHUNK); +pub type BlockZ = BlockCoord<{ axis::Z }>; /// X and Z coordinates of a block in a chunk #[derive(Clone, Copy, PartialEq, Eq)] @@ -118,16 +137,13 @@ impl Debug for SectionBlockCoords { pub struct SectionY(pub i32); pub const CHUNKS_PER_REGION: usize = 32; +coord_type!(ChunkCoord, CHUNKS_PER_REGION); /// A chunk X coordinate relative to a region -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ChunkX(pub u8); -coord_impl!(ChunkX, CHUNKS_PER_REGION); +pub type ChunkX = ChunkCoord<{ axis::X }>; /// A chunk Z coordinate relative to a region -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct ChunkZ(pub u8); -coord_impl!(ChunkZ, CHUNKS_PER_REGION); +pub type ChunkZ = ChunkCoord<{ axis::Z }>; /// A pair of chunk coordinates relative to a region #[derive(Clone, Copy, PartialEq, Eq)] From 5a765c3862a7f3233e53a20393c9cf2071cb3e4e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 00:54:28 +0200 Subject: [PATCH 200/460] minedmap/region_group: add RegionGroup type A generic array of 3x3 elements. --- src/bin/minedmap/main.rs | 1 + src/bin/minedmap/region_group.rs | 80 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/bin/minedmap/region_group.rs diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 34aa985..8d3bbea 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -1,5 +1,6 @@ mod common; mod metadata_writer; +mod region_group; mod region_processor; mod tile_mipmapper; mod tile_renderer; diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs new file mode 100644 index 0000000..0a12fd8 --- /dev/null +++ b/src/bin/minedmap/region_group.rs @@ -0,0 +1,80 @@ +use std::iter; + +use anyhow::Result; + +/// A generic array of 3x3 elements +/// +/// A RegionGroup is used to store information about a 3x3 neighbourhood of +/// regions. +/// +/// The center element is always populated, while the 8 adjacent elements may be None. +#[derive(Debug, Clone, Copy)] +pub struct RegionGroup { + center: T, + neighs: [Option; 8], +} + +impl RegionGroup { + pub fn new(f: F) -> Result + where + F: Fn(i8, i8) -> Result, + { + RegionGroup { + center: (0, 0), + neighs: [ + Some((-1, -1)), + Some((-1, 0)), + Some((-1, 1)), + Some((0, -1)), + Some((0, 1)), + Some((1, -1)), + Some((1, 0)), + Some((1, 1)), + ], + } + .try_map(|(x, z)| f(x, z)) + } + + pub fn center(&self) -> &T { + &self.center + } + + pub fn get(&self, x: i8, z: i8) -> Option<&T> { + match (x, z) { + (0, 0) => Some(&self.center), + (-1, -1) => self.neighs[0].as_ref(), + (-1, 0) => self.neighs[1].as_ref(), + (-1, 1) => self.neighs[2].as_ref(), + (0, -1) => self.neighs[3].as_ref(), + (0, 1) => self.neighs[4].as_ref(), + (1, -1) => self.neighs[5].as_ref(), + (1, 0) => self.neighs[6].as_ref(), + (1, 1) => self.neighs[7].as_ref(), + _ => panic!("index out of bounds"), + } + } + + pub fn map(self, mut f: F) -> RegionGroup + where + F: FnMut(T) -> U, + { + RegionGroup { + center: f(self.center), + neighs: self.neighs.map(|entry| entry.map(|v| f(v))), + } + } + + pub fn try_map(self, mut f: F) -> Result> + where + F: FnMut(T) -> Result, + { + let RegionGroup { center, neighs } = self; + let center = f(center)?; + let neighs = neighs.map(|entry| entry.map(|value| f(value).ok()).flatten()); + Ok(RegionGroup { center, neighs }) + } + + pub fn iter(&self) -> impl Iterator { + iter::once(&self.center).chain(self.neighs.iter().filter_map(Option::as_ref)) + } +} From a30266f67f417bba0e646b3caebbefaa2f7ac8ac Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Aug 2023 23:15:52 +0200 Subject: [PATCH 201/460] minedmap/tile_renderer: take into account neighboring regions Biome smoothing uses biome data from neighboring regions. Collect paths and timestamps from 3x3 region groups. --- src/bin/minedmap/tile_renderer.rs | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 70b55de..e416d50 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,4 +1,7 @@ -use std::path::Path; +use std::{ + path::{Path, PathBuf}, + time::SystemTime, +}; use anyhow::{Context, Result}; @@ -8,7 +11,7 @@ use minedmap::{ types::*, }; -use super::common::*; +use super::{common::*, region_group::RegionGroup}; pub struct TileRenderer<'a> { config: &'a Config, @@ -57,11 +60,35 @@ impl<'a> TileRenderer<'a> { } } + fn processed_source(&self, coords: TileCoords) -> Result<(PathBuf, SystemTime)> { + let path = self.config.processed_path(coords); + let timestamp = fs::modified_timestamp(&path)?; + Ok((path, timestamp)) + } + + fn processed_sources(&self, coords: TileCoords) -> Result<(RegionGroup, SystemTime)> { + let sources = RegionGroup::new(|x, z| { + self.processed_source(TileCoords { + x: coords.x + (x as i32), + z: coords.z + (z as i32), + }) + }) + .with_context(|| format!("Region {:?} from previous step must exist", coords))?; + + let max_timestamp = *sources + .iter() + .map(|(_, timestamp)| timestamp) + .max() + .expect("at least one timestamp must exist"); + + let paths = sources.map(|(path, _)| path); + Ok((paths, max_timestamp)) + } + fn render_tile(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - let processed_path = self.config.processed_path(coords); - let processed_timestamp = fs::modified_timestamp(&processed_path)?; + let (processed_paths, processed_timestamp) = self.processed_sources(coords)?; let output_path = self.config.tile_path(TileKind::Map, 0, coords); let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); @@ -85,7 +112,7 @@ impl<'a> TileRenderer<'a> { .display(), ); - let region = Self::load_region(&processed_path)?; + let region = Self::load_region(processed_paths.center())?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion); From 35bbd167bae771a8a870864f49c51073591da25f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 18:01:29 +0200 Subject: [PATCH 202/460] minedmap/tile_renderer: load 3x3 neighbourhoods of regions Prepare for biome smoothing by always loading neighbouring regions. --- src/bin/minedmap/tile_renderer.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index e416d50..9737e7b 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -26,6 +26,12 @@ impl<'a> TileRenderer<'a> { storage::read(processed_path).context("Failed to load processed region data") } + fn load_region_group( + processed_paths: RegionGroup, + ) -> Result> { + processed_paths.try_map(|path| Self::load_region(&path)) + } + fn render_chunk(image: &mut image::RgbaImage, coords: ChunkCoords, chunk: &ProcessedChunk) { const N: u32 = BLOCKS_PER_CHUNK as u32; @@ -50,8 +56,8 @@ impl<'a> TileRenderer<'a> { overlay_chunk(image, &chunk_image, coords); } - fn render_region(image: &mut image::RgbaImage, region: &ProcessedRegion) { - for (coords, chunk) in region.iter() { + fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { + for (coords, chunk) in region_group.center().iter() { let Some(chunk) = chunk else { continue; }; @@ -112,9 +118,10 @@ impl<'a> TileRenderer<'a> { .display(), ); - let region = Self::load_region(processed_paths.center())?; + let region_group = Self::load_region_group(processed_paths) + .with_context(|| format!("Region {:?} from previous step must be loadable", coords))?; let mut image = image::RgbaImage::new(N, N); - Self::render_region(&mut image, ®ion); + Self::render_region(&mut image, ®ion_group); fs::create_with_timestamp( &output_path, From dee00e7a02d6e7f853abb817e56b56f6133a3c57 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 2 Aug 2023 21:51:59 +0200 Subject: [PATCH 203/460] minedmap/tile_renderer: add coord_offset() helper --- src/bin/minedmap/tile_renderer.rs | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 9737e7b..8988425 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -4,6 +4,7 @@ use std::{ }; use anyhow::{Context, Result}; +use num_integer::div_mod_floor; use minedmap::{ io::{fs, storage}, @@ -13,6 +14,29 @@ use minedmap::{ use super::{common::*, region_group::RegionGroup}; +/// Offsets a chunk and block coordinate pair by a number of blocks +/// +/// As the new coordinate may end up in a different region, a region offset +/// is returned together with the new chunk and block coordinates. +fn coord_offset( + chunk: ChunkCoord, + block: BlockCoord, + offset: i32, +) -> (i8, ChunkCoord, BlockCoord) { + const CHUNKS: i32 = CHUNKS_PER_REGION as i32; + const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32; + let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset; + let (region_chunk, block) = div_mod_floor(coord, BLOCKS); + let (region, chunk) = div_mod_floor(region_chunk, CHUNKS); + ( + region + .try_into() + .expect("the region coordinate should be in the valid range"), + ChunkCoord::new(chunk), + BlockCoord::new(block), + ) +} + pub struct TileRenderer<'a> { config: &'a Config, } @@ -147,3 +171,37 @@ impl<'a> TileRenderer<'a> { Ok(()) } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_coord_offset() { + const CHUNKS: i32 = CHUNKS_PER_REGION as i32; + const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32; + + for chunk in ChunkX::iter() { + for block in BlockX::iter() { + assert_eq!(coord_offset(chunk, block, 0), (0, chunk, block)); + assert_eq!( + coord_offset(chunk, block, -(CHUNKS * BLOCKS)), + (-1, chunk, block) + ); + assert_eq!( + coord_offset(chunk, block, CHUNKS * BLOCKS), + (1, chunk, block) + ); + + for offset in -(CHUNKS * BLOCKS)..(CHUNKS * BLOCKS) { + let (region2, chunk2, block2) = coord_offset(chunk, block, offset); + assert!((-1..=1).contains(®ion2)); + let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset; + let coord2 = + ((region2 as i32 * CHUNKS) + chunk2.0 as i32) * BLOCKS + block2.0 as i32; + assert_eq!(coord2, coord); + } + } + } + } +} From 8e848394cdb9f201742e5541a7f82660f389cc7c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 17:51:44 +0200 Subject: [PATCH 204/460] minedmap/tile_renderer: add biome_at() helper Retrieve the biome at a given coordinate, possibly offset by a number of blocks. --- src/bin/minedmap/tile_renderer.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 8988425..50105cd 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -8,7 +8,7 @@ use num_integer::div_mod_floor; use minedmap::{ io::{fs, storage}, - resource::block_color, + resource::{block_color, Biome}, types::*, }; @@ -37,6 +37,27 @@ fn coord_offset( ) } +fn biome_at( + region_group: &RegionGroup, + chunk: ChunkCoords, + block: LayerBlockCoords, + dx: i32, + dz: i32, +) -> Option<&Biome> { + let (region_x, chunk_x, block_x) = coord_offset(chunk.x, block.x, dx); + let (region_z, chunk_z, block_z) = coord_offset(chunk.z, block.z, dz); + let chunk = ChunkCoords { + x: chunk_x, + z: chunk_z, + }; + let block = LayerBlockCoords { + x: block_x, + z: block_z, + }; + let region = region_group.get(region_x, region_z)?; + region[chunk].as_ref()?.biomes[block].as_ref() +} + pub struct TileRenderer<'a> { config: &'a Config, } From 45171aa26a0c0d21cbd518d08d53851d2acbd009 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 18:12:56 +0200 Subject: [PATCH 205/460] minedmap/tile_renderer: factor out block_color_at() from render_chunk() Also pass in a few more values to prepare for biome smoothing. --- src/bin/minedmap/tile_renderer.rs | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 50105cd..2dcdedd 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -77,28 +77,35 @@ impl<'a> TileRenderer<'a> { processed_paths.try_map(|path| Self::load_region(&path)) } - fn render_chunk(image: &mut image::RgbaImage, coords: ChunkCoords, chunk: &ProcessedChunk) { + fn block_color_at( + _region_group: &RegionGroup, + chunk: &ProcessedChunk, + _chunk_coords: ChunkCoords, + block_coords: LayerBlockCoords, + ) -> Option<[u8; 4]> { + let block = chunk.blocks[block_coords]?; + let depth = chunk.depths[block_coords]?; + let biome = chunk.biomes[block_coords].as_ref()?; + Some(block_color(block, biome, depth.0 as f32)) + } + + fn render_chunk( + image: &mut image::RgbaImage, + region_group: &RegionGroup, + chunk: &ProcessedChunk, + chunk_coords: ChunkCoords, + ) { const N: u32 = BLOCKS_PER_CHUNK as u32; let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { - let coords = LayerBlockCoords { + let block_coords = LayerBlockCoords { x: BlockX::new(x), z: BlockZ::new(z), }; - image::Rgba( - match ( - &chunk.blocks[coords], - &chunk.biomes[coords], - &chunk.depths[coords], - ) { - (Some(block), Some(biome), Some(depth)) => { - block_color(*block, biome, depth.0 as f32) - } - _ => [0, 0, 0, 0], - }, - ) + let color = Self::block_color_at(region_group, chunk, chunk_coords, block_coords); + image::Rgba(color.unwrap_or_default()) }); - overlay_chunk(image, &chunk_image, coords); + overlay_chunk(image, &chunk_image, chunk_coords); } fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { @@ -107,7 +114,7 @@ impl<'a> TileRenderer<'a> { continue; }; - Self::render_chunk(image, coords, chunk); + Self::render_chunk(image, region_group, chunk, coords); } } From 0a485343a047890cb6342a254e6f0e71a34dc6fc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 18:28:57 +0200 Subject: [PATCH 206/460] resource: do not require Biome to get color for all block types Only grass, foliage and water have biome-dependent colors. --- src/bin/minedmap/tile_renderer.rs | 10 ++++++++-- src/resource/block_color.rs | 16 ++++++++++++---- src/resource/mod.rs | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 2dcdedd..fed99bb 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -8,7 +8,7 @@ use num_integer::div_mod_floor; use minedmap::{ io::{fs, storage}, - resource::{block_color, Biome}, + resource::{block_color, needs_biome, Biome}, types::*, }; @@ -85,8 +85,14 @@ impl<'a> TileRenderer<'a> { ) -> Option<[u8; 4]> { let block = chunk.blocks[block_coords]?; let depth = chunk.depths[block_coords]?; + + if !needs_biome(block) { + return Some(block_color(block, None, depth.0 as f32)); + } + let biome = chunk.biomes[block_coords].as_ref()?; - Some(block_color(block, biome, depth.0 as f32)) + + Some(block_color(block, Some(biome), depth.0 as f32)) } fn render_chunk( diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index c239d96..0b6e935 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -72,16 +72,24 @@ impl BiomeExt for Biome { const BIRCH_COLOR: Vec3 = Vec3::new(0.502, 0.655, 0.333); // == color_vec(Color([128, 167, 85])) const EVERGREEN_COLOR: Vec3 = Vec3::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) -pub fn block_color(block: BlockType, biome: &Biome, depth: f32) -> [u8; 4] { +pub fn needs_biome(block: BlockType) -> bool { use super::BlockFlag::*; + block.is(Grass) || block.is(Foliage) || block.is(Water) +} + +pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> [u8; 4] { + use super::BlockFlag::*; + + let get_biome = || biome.expect("needs biome to determine block color"); + let mut color = color_vec_unscaled(block.color); if block.is(Grass) { - color *= biome.grass_color(depth); + color *= get_biome().grass_color(depth); } if block.is(Foliage) { - color *= biome.foliage_color(depth); + color *= get_biome().foliage_color(depth); } if block.is(Birch) { color *= BIRCH_COLOR; @@ -90,7 +98,7 @@ pub fn block_color(block: BlockType, biome: &Biome, depth: f32) -> [u8; 4] { color *= EVERGREEN_COLOR; } if block.is(Water) { - color *= biome.water_color(); + color *= get_biome().water_color(); } color *= 0.5 + 0.005 * depth; diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 7095f68..921fdc2 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -91,7 +91,7 @@ impl BlockTypes { } pub use biomes::{Biome, BiomeGrassColorModifier}; -pub use block_color::block_color; +pub use block_color::{block_color, needs_biome}; #[derive(Debug)] pub struct BiomeTypes { From b650b096ef13563d017d41151ad14323dda3fc8e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 18:31:45 +0200 Subject: [PATCH 207/460] resource: return block color as float vector Deferring conversion to integers is convenient for biome smoothing. --- src/bin/minedmap/tile_renderer.rs | 9 +++++++-- src/resource/block_color.rs | 6 ++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index fed99bb..c931c72 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -4,6 +4,7 @@ use std::{ }; use anyhow::{Context, Result}; +use glam::Vec3; use num_integer::div_mod_floor; use minedmap::{ @@ -82,7 +83,7 @@ impl<'a> TileRenderer<'a> { chunk: &ProcessedChunk, _chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, - ) -> Option<[u8; 4]> { + ) -> Option { let block = chunk.blocks[block_coords]?; let depth = chunk.depths[block_coords]?; @@ -109,7 +110,11 @@ impl<'a> TileRenderer<'a> { z: BlockZ::new(z), }; let color = Self::block_color_at(region_group, chunk, chunk_coords, block_coords); - image::Rgba(color.unwrap_or_default()) + image::Rgba( + color + .map(|c| [c[0] as u8, c[1] as u8, c[2] as u8, 255]) + .unwrap_or_default(), + ) }); overlay_chunk(image, &chunk_image, chunk_coords); } diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index 0b6e935..b98aec9 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -78,7 +78,7 @@ pub fn needs_biome(block: BlockType) -> bool { block.is(Grass) || block.is(Foliage) || block.is(Water) } -pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> [u8; 4] { +pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> Vec3 { use super::BlockFlag::*; let get_biome = || biome.expect("needs biome to determine block color"); @@ -101,7 +101,5 @@ pub fn block_color(block: BlockType, biome: Option<&Biome>, depth: f32) -> [u8; color *= get_biome().water_color(); } - color *= 0.5 + 0.005 * depth; - - [color[0] as u8, color[1] as u8, color[2] as u8, 255] + color * (0.5 + 0.005 * depth) } From c38f00e4114c071463429801b9bb5fcb314b3291 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 19:06:20 +0200 Subject: [PATCH 208/460] minedmap/tile_renderer: implement biome smoothing Rather than the diamond-shaped kernel used by the old implemenation, we now use the approximation of a Gauss filter. In addition, the kernel size is decreased, reducing the strength of the blur effect. --- src/bin/minedmap/tile_renderer.rs | 32 +++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index c931c72..c66431f 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -79,11 +79,15 @@ impl<'a> TileRenderer<'a> { } fn block_color_at( - _region_group: &RegionGroup, + region_group: &RegionGroup, chunk: &ProcessedChunk, - _chunk_coords: ChunkCoords, + chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, ) -> Option { + const SMOOTH: [[f32; 3]; 3] = [[41.0, 26.0, 7.0], [26.0, 16.0, 4.0], [7.0, 4.0, 1.0]]; + const X: isize = SMOOTH[0].len() as isize - 1; + const Z: isize = SMOOTH.len() as isize - 1; + let block = chunk.blocks[block_coords]?; let depth = chunk.depths[block_coords]?; @@ -91,9 +95,29 @@ impl<'a> TileRenderer<'a> { return Some(block_color(block, None, depth.0 as f32)); } - let biome = chunk.biomes[block_coords].as_ref()?; + let mut total = 0.0; + let mut color = Vec3::ZERO; + for dz in -Z..=Z { + for dx in -X..=X { + let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()]; + if w == 0.0 { + continue; + } - Some(block_color(block, Some(biome), depth.0 as f32)) + let Some(biome) = biome_at(region_group, chunk_coords, block_coords, dx as i32, dz as i32) else { + continue; + }; + + total += w; + color += w * block_color(block, Some(biome), depth.0 as f32); + } + } + + if total == 0.0 { + return None; + } + + Some(color / total) } fn render_chunk( From fb712cd2f5a15dedf29bd68bb54add9684352acc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 21:27:08 +0200 Subject: [PATCH 209/460] Store per-region biome list in IndexSet Index into the biome list instead of duplicating the biome data for each coordinate. This reduces the size of the processed data and speeds up encoding/decoding. --- Cargo.lock | 24 ++++++++++++++++++++++++ Cargo.toml | 1 + src/bin/minedmap/common.rs | 10 ++++++++-- src/bin/minedmap/region_processor.rs | 15 ++++++++++----- src/bin/minedmap/tile_renderer.rs | 5 +++-- src/resource/biomes.rs | 4 ++-- src/resource/mod.rs | 2 +- src/world/layer.rs | 27 +++++++++++++++++++++------ 8 files changed, 70 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b286664..d771fd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,12 @@ dependencies = [ "syn", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.2" @@ -279,6 +285,12 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -305,6 +317,17 @@ dependencies = [ "png", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.9" @@ -375,6 +398,7 @@ dependencies = [ "flate2", "glam", "image", + "indexmap", "itertools", "num-integer", "serde", diff --git a/Cargo.toml b/Cargo.toml index 5e04100..aad8ff8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ fastnbt = "2.3.2" flate2 = "1.0.25" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } +indexmap = { version = "2.0.0", features = ["serde"] } itertools = "0.11.0" num-integer = "0.1.45" serde = "1.0.152" diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index a108e8d..eb1613e 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -4,9 +4,10 @@ use std::{ path::{Path, PathBuf}, }; +use indexmap::IndexSet; use serde::{Deserialize, Serialize}; -use minedmap::{io::fs::FileMetaVersion, types::*, world::layer}; +use minedmap::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; // Increase to force regeneration of all output files pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); @@ -43,7 +44,12 @@ pub struct ProcessedChunk { pub biomes: Box, pub depths: Box, } -pub type ProcessedRegion = ChunkArray>; + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct ProcessedRegion { + pub biome_list: IndexSet, + pub chunks: ChunkArray>, +} pub struct Config { pub region_dir: PathBuf, diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index f2720c7..8a77a73 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -2,9 +2,10 @@ use std::{path::Path, time::SystemTime}; use anyhow::{Context, Result}; +use indexmap::IndexSet; use minedmap::{ io::{fs, storage}, - resource, + resource::{self, Biome}, types::*, world::{ self, @@ -45,9 +46,13 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single chunk - fn process_chunk(&self, data: world::de::Chunk) -> Result> { + fn process_chunk( + &self, + biome_list: &mut IndexSet, + data: world::de::Chunk, + ) -> Result> { let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; - world::layer::top_layer(&chunk) + world::layer::top_layer(biome_list, &chunk) } fn render_chunk_lightmap( @@ -110,12 +115,12 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData{ blocks, biomes, block_light, depths }) = self - .process_chunk(data) + .process_chunk(&mut processed_region.biome_list, data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { return Ok(()); }; - processed_region[chunk_coords] = Some(ProcessedChunk { + processed_region.chunks[chunk_coords] = Some(ProcessedChunk { blocks, biomes, depths, diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index c66431f..556483b 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -56,7 +56,8 @@ fn biome_at( z: block_z, }; let region = region_group.get(region_x, region_z)?; - region[chunk].as_ref()?.biomes[block].as_ref() + let index = region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1; + region.biome_list.get_index(index.into()) } pub struct TileRenderer<'a> { @@ -144,7 +145,7 @@ impl<'a> TileRenderer<'a> { } fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { - for (coords, chunk) in region_group.center().iter() { + for (coords, chunk) in region_group.center().chunks.iter() { let Some(chunk) = chunk else { continue; }; diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs index cf0db4b..0515e93 100644 --- a/src/resource/biomes.rs +++ b/src/resource/biomes.rs @@ -2,13 +2,13 @@ use serde::{Deserialize, Serialize}; use super::Color; -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum BiomeGrassColorModifier { DarkForest, Swamp, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Biome { pub temp: i8, pub downfall: i8, diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 921fdc2..5eb2838 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -35,7 +35,7 @@ where BitFlags::::from_bits(bits).map_err(de::Error::custom) } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Color(pub [u8; 3]); #[derive(Debug, Clone, Copy, Serialize, Deserialize)] diff --git a/src/world/layer.rs b/src/world/layer.rs index 4b23f26..fa9a4f7 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -1,4 +1,7 @@ +use std::num::NonZeroU16; + use anyhow::{Context, Result}; +use indexmap::IndexSet; use serde::{Deserialize, Serialize}; use super::chunk::{Chunk, SectionIterItem}; @@ -26,13 +29,13 @@ impl BlockHeight { } pub type BlockArray = LayerBlockArray>; -pub type BiomeArray = LayerBlockArray>; +pub type BiomeArray = LayerBlockArray>; pub type BlockLightArray = LayerBlockArray; pub type DepthArray = LayerBlockArray>; struct LayerEntry<'a> { block: &'a mut Option, - biome: &'a mut Option, + biome: &'a mut Option, block_light: &'a mut u8, depth: &'a mut Option, } @@ -46,7 +49,12 @@ impl<'a> LayerEntry<'a> { self.depth.is_some() } - fn fill(&mut self, section: SectionIterItem, coords: SectionBlockCoords) -> Result { + fn fill( + &mut self, + biome_list: &mut IndexSet, + section: SectionIterItem, + coords: SectionBlockCoords, + ) -> Result { let Some(block_type) = section.section.block_at(coords)? .filter(|block_type| block_type.is(BlockFlag::Opaque)) else { @@ -59,7 +67,14 @@ impl<'a> LayerEntry<'a> { if self.is_empty() { *self.block = Some(block_type); - *self.biome = section.biomes.biome_at(section.y, coords)?.copied(); + 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"), + ); + } } if block_type.is(BlockFlag::Water) { @@ -99,7 +114,7 @@ impl LayerData { /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block /// is additionally filled in as the water depth. -pub fn top_layer(chunk: &Chunk) -> Result> { +pub fn top_layer(biome_list: &mut IndexSet, chunk: &Chunk) -> Result> { use BLOCKS_PER_CHUNK as N; if chunk.is_empty() { @@ -121,7 +136,7 @@ pub fn top_layer(chunk: &Chunk) -> Result> { } let coords = SectionBlockCoords { xz, y }; - if !entry.fill(section, coords)? { + if !entry.fill(biome_list, section, coords)? { continue; } From deb33814eef34046dda53cf597a4d80842fea90d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Aug 2023 23:02:49 +0200 Subject: [PATCH 210/460] minedmap/tile_renderer: avoid calling block_color() more often than necessary Collect all biome indices/weights for a chunk and deduplicate using a hash map. --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/bin/minedmap/tile_renderer.rs | 30 +++++++++++++++++++++--------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d771fd3..b525be4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,6 +401,7 @@ dependencies = [ "indexmap", "itertools", "num-integer", + "rustc-hash", "serde", "serde_json", "zstd", @@ -489,6 +490,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.4" diff --git a/Cargo.toml b/Cargo.toml index aad8ff8..c74b56a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } itertools = "0.11.0" num-integer = "0.1.45" +rustc-hash = "1.1.0" serde = "1.0.152" serde_json = "1.0.99" zstd = "0.12.3" diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 556483b..76485bb 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -9,7 +9,7 @@ use num_integer::div_mod_floor; use minedmap::{ io::{fs, storage}, - resource::{block_color, needs_biome, Biome}, + resource::{block_color, needs_biome}, types::*, }; @@ -44,7 +44,7 @@ fn biome_at( block: LayerBlockCoords, dx: i32, dz: i32, -) -> Option<&Biome> { +) -> Option<(i8, i8, u16)> { let (region_x, chunk_x, block_x) = coord_offset(chunk.x, block.x, dx); let (region_z, chunk_z, block_z) = coord_offset(chunk.z, block.z, dz); let chunk = ChunkCoords { @@ -56,8 +56,11 @@ fn biome_at( z: block_z, }; let region = region_group.get(region_x, region_z)?; - let index = region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1; - region.biome_list.get_index(index.into()) + Some(( + region_x, + region_z, + region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1, + )) } pub struct TileRenderer<'a> { @@ -96,8 +99,7 @@ impl<'a> TileRenderer<'a> { return Some(block_color(block, None, depth.0 as f32)); } - let mut total = 0.0; - let mut color = Vec3::ZERO; + let mut weights = rustc_hash::FxHashMap::<(i8, i8, u16), f32>::default(); for dz in -Z..=Z { for dx in -X..=X { let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()]; @@ -109,15 +111,25 @@ impl<'a> TileRenderer<'a> { continue; }; - total += w; - color += w * block_color(block, Some(biome), depth.0 as f32); + *weights.entry(biome).or_default() += w; } } - if total == 0.0 { + if weights.is_empty() { return None; } + let mut color = Vec3::ZERO; + let mut total = 0.0; + + for ((region_x, region_z, index), w) in weights { + let region = region_group.get(region_x, region_z)?; + let biome = region.biome_list.get_index(index.into())?; + + total += w; + color += w * block_color(block, Some(biome), depth.0 as f32); + } + Some(color / total) } From dc68e67a234c044b0c608e923d46f92ef8139977 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 4 Aug 2023 00:46:58 +0200 Subject: [PATCH 211/460] minedmap/region_group: clippy fixes --- src/bin/minedmap/region_group.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index 0a12fd8..1c08296 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -60,7 +60,7 @@ impl RegionGroup { { RegionGroup { center: f(self.center), - neighs: self.neighs.map(|entry| entry.map(|v| f(v))), + neighs: self.neighs.map(|entry| entry.map(&mut f)), } } @@ -70,7 +70,7 @@ impl RegionGroup { { let RegionGroup { center, neighs } = self; let center = f(center)?; - let neighs = neighs.map(|entry| entry.map(|value| f(value).ok()).flatten()); + let neighs = neighs.map(|entry| entry.and_then(|value| f(value).ok())); Ok(RegionGroup { center, neighs }) } From ab3b273992137afe525ed2bb1e3bda23b47636dd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 4 Aug 2023 16:13:08 +0200 Subject: [PATCH 212/460] Update dependencies --- Cargo.lock | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b525be4..b1bfe6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,11 +104,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -381,9 +382,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "minedmap" @@ -498,9 +499,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" dependencies = [ "bitflags 2.3.3", "errno", @@ -517,9 +518,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.178" +version = "1.0.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" +checksum = "6d3e73c93c3240c0bda063c239298e633114c69a888c3e37ca8bb33f343e9890" dependencies = [ "serde_derive", ] @@ -535,9 +536,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.178" +version = "1.0.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" +checksum = "be02f6cb0cd3a5ec20bbcfbcbd749f57daddb1a0882dc2e46a6c236c90b977ed" dependencies = [ "proc-macro2", "quote", @@ -569,9 +570,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.27" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", From 7d231b92ea1ae524907e13ff4320450194bc9ab0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 10:46:47 +0200 Subject: [PATCH 213/460] Format let-else blocks Use nightly rustfmt to format let-else. --- src/bin/minedmap/region_processor.rs | 11 ++++++++--- src/bin/minedmap/tile_renderer.rs | 8 +++++++- src/world/layer.rs | 4 +++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 8a77a73..6600844 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -20,8 +20,8 @@ fn parse_region_filename(path: &Path) -> Option { let file_name = path.file_name()?.to_str()?; let parts: Vec<_> = file_name.split('.').collect(); let &["r", x, z, "mca"] = parts.as_slice() else { - return None; - }; + return None; + }; Some(TileCoords { x: x.parse().ok()?, @@ -114,7 +114,12 @@ impl<'a> RegionProcessor<'a> { minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { - let Some(layer::LayerData{ blocks, biomes, block_light, depths }) = self + let Some(layer::LayerData { + blocks, + biomes, + block_light, + depths, + }) = self .process_chunk(&mut processed_region.biome_list, data) .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? else { diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 76485bb..efede58 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -107,7 +107,13 @@ impl<'a> TileRenderer<'a> { continue; } - let Some(biome) = biome_at(region_group, chunk_coords, block_coords, dx as i32, dz as i32) else { + let Some(biome) = biome_at( + region_group, + chunk_coords, + block_coords, + dx as i32, + dz as i32, + ) else { continue; }; diff --git a/src/world/layer.rs b/src/world/layer.rs index fa9a4f7..3abc30b 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -55,7 +55,9 @@ impl<'a> LayerEntry<'a> { section: SectionIterItem, coords: SectionBlockCoords, ) -> Result { - let Some(block_type) = section.section.block_at(coords)? + let Some(block_type) = section + .section + .block_at(coords)? .filter(|block_type| block_type.is(BlockFlag::Opaque)) else { if self.is_empty() { From cd1a5e869dbafa11a50e99e193e05bcc5da7c334 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 11:17:52 +0200 Subject: [PATCH 214/460] minedmap/region_group: optimize get() implementation --- src/bin/minedmap/region_group.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index 1c08296..4e7c636 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -40,18 +40,23 @@ impl RegionGroup { } pub fn get(&self, x: i8, z: i8) -> Option<&T> { - match (x, z) { - (0, 0) => Some(&self.center), - (-1, -1) => self.neighs[0].as_ref(), - (-1, 0) => self.neighs[1].as_ref(), - (-1, 1) => self.neighs[2].as_ref(), - (0, -1) => self.neighs[3].as_ref(), - (0, 1) => self.neighs[4].as_ref(), - (1, -1) => self.neighs[5].as_ref(), - (1, 0) => self.neighs[6].as_ref(), - (1, 1) => self.neighs[7].as_ref(), - _ => panic!("index out of bounds"), - } + let index = match (x, z) { + (0, 0) => { + return Some(&self.center); + } + (-1, -1) => 0, + (-1, 0) => 1, + (-1, 1) => 2, + (0, -1) => 3, + (0, 1) => 4, + (1, -1) => 5, + (1, 0) => 6, + (1, 1) => 7, + _ => { + return None; + } + }; + self.neighs[index].as_ref() } pub fn map(self, mut f: F) -> RegionGroup From 7b46adf6e78c6638b69ebfbf2e133589b0d00067 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 14:21:51 +0200 Subject: [PATCH 215/460] minedmap: split up big types by adding Boxes Make these values faster to move around, and optimize their size when used in Options. --- src/bin/minedmap/common.rs | 2 +- src/bin/minedmap/region_processor.rs | 4 ++-- src/bin/minedmap/tile_renderer.rs | 15 +++++++++------ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index eb1613e..44c7ae4 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -48,7 +48,7 @@ pub struct ProcessedChunk { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ProcessedRegion { pub biome_list: IndexSet, - pub chunks: ChunkArray>, + pub chunks: ChunkArray>>, } pub struct Config { diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 6600844..34c9555 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -125,11 +125,11 @@ impl<'a> RegionProcessor<'a> { else { return Ok(()); }; - processed_region.chunks[chunk_coords] = Some(ProcessedChunk { + processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { blocks, biomes, depths, - }); + })); let chunk_lightmap = Self::render_chunk_lightmap(block_light); overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index efede58..646e098 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -39,7 +39,7 @@ fn coord_offset( } fn biome_at( - region_group: &RegionGroup, + region_group: &RegionGroup>, chunk: ChunkCoords, block: LayerBlockCoords, dx: i32, @@ -72,18 +72,18 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } - fn load_region(processed_path: &Path) -> Result { + fn load_region(processed_path: &Path) -> Result> { storage::read(processed_path).context("Failed to load processed region data") } fn load_region_group( processed_paths: RegionGroup, - ) -> Result> { + ) -> Result>> { processed_paths.try_map(|path| Self::load_region(&path)) } fn block_color_at( - region_group: &RegionGroup, + region_group: &RegionGroup>, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, @@ -141,7 +141,7 @@ impl<'a> TileRenderer<'a> { fn render_chunk( image: &mut image::RgbaImage, - region_group: &RegionGroup, + region_group: &RegionGroup>, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, ) { @@ -162,7 +162,10 @@ impl<'a> TileRenderer<'a> { overlay_chunk(image, &chunk_image, chunk_coords); } - fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { + fn render_region( + image: &mut image::RgbaImage, + region_group: &RegionGroup>, + ) { for (coords, chunk) in region_group.center().chunks.iter() { let Some(chunk) = chunk else { continue; From 521e799d4b7c071bfef4645f06f8c8f9b9ca4d84 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 14:36:59 +0200 Subject: [PATCH 216/460] minedmap/region_group: make indexing into the neighbor array more uniform Add a 9th element, so the 3x3 entries can always be indexed the same way, leading to a slight performance improvement. The center element is always None. --- src/bin/minedmap/region_group.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index 4e7c636..aa7088c 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -11,7 +11,7 @@ use anyhow::Result; #[derive(Debug, Clone, Copy)] pub struct RegionGroup { center: T, - neighs: [Option; 8], + neighs: [Option; 9], } impl RegionGroup { @@ -26,6 +26,7 @@ impl RegionGroup { Some((-1, 0)), Some((-1, 1)), Some((0, -1)), + None, Some((0, 1)), Some((1, -1)), Some((1, 0)), @@ -40,23 +41,13 @@ impl RegionGroup { } pub fn get(&self, x: i8, z: i8) -> Option<&T> { - let index = match (x, z) { - (0, 0) => { - return Some(&self.center); - } - (-1, -1) => 0, - (-1, 0) => 1, - (-1, 1) => 2, - (0, -1) => 3, - (0, 1) => 4, - (1, -1) => 5, - (1, 0) => 6, - (1, 1) => 7, - _ => { - return None; - } - }; - self.neighs[index].as_ref() + if (x, z) == (0, 0) { + return Some(&self.center); + } + if !(-1..=1).contains(&x) || !(-1..=1).contains(&z) { + return None; + } + self.neighs.get((3 * x + z + 4) as usize)?.as_ref() } pub fn map(self, mut f: F) -> RegionGroup From 84bee6d6d99baca742675613e04e2bf9ccd6e3c9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 20:13:35 +0200 Subject: [PATCH 217/460] minedmap: add region cache Cache the last loaded processed regions. --- Cargo.lock | 37 ++++++++++++++++++++++++++ Cargo.toml | 3 ++- src/bin/minedmap/main.rs | 8 ++++-- src/bin/minedmap/tile_renderer.rs | 43 +++++++++++++++++++++++-------- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1bfe6e..839c9ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,23 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "anstream" version = "0.3.2" @@ -291,6 +308,10 @@ name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "heck" @@ -386,6 +407,15 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +[[package]] +name = "lru" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +dependencies = [ + "hashbrown", +] + [[package]] name = "minedmap" version = "0.1.0" @@ -401,6 +431,7 @@ dependencies = [ "image", "indexmap", "itertools", + "lru", "num-integer", "rustc-hash", "serde", @@ -591,6 +622,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index c74b56a..5d74ce8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,10 @@ glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } itertools = "0.11.0" +lru = "0.11.0" num-integer = "0.1.45" rustc-hash = "1.1.0" -serde = "1.0.152" +serde = { version = "1.0.152", features = ["rc"] } serde_json = "1.0.99" zstd = "0.12.3" diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 8d3bbea..838728c 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; use anyhow::Result; use clap::Parser; -use common::Config; +use common::{Config, TileCoords}; use metadata_writer::MetadataWriter; use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; @@ -28,7 +28,11 @@ fn main() -> Result<()> { let args = Args::parse(); let config = Config::new(args); - let regions = RegionProcessor::new(&config).run()?; + let mut regions = RegionProcessor::new(&config).run()?; + + // 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 })); + TileRenderer::new(&config).run(®ions)?; let tiles = TileMipmapper::new(&config).run(®ions)?; MetadataWriter::new(&config).run(tiles)?; diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 646e098..abacffd 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,10 +1,13 @@ use std::{ + num::NonZeroUsize, path::{Path, PathBuf}, + rc::Rc, time::SystemTime, }; use anyhow::{Context, Result}; use glam::Vec3; +use lru::LruCache; use num_integer::div_mod_floor; use minedmap::{ @@ -39,7 +42,7 @@ fn coord_offset( } fn biome_at( - region_group: &RegionGroup>, + region_group: &RegionGroup>, chunk: ChunkCoords, block: LayerBlockCoords, dx: i32, @@ -72,18 +75,30 @@ impl<'a> TileRenderer<'a> { TileRenderer { config } } - fn load_region(processed_path: &Path) -> Result> { - storage::read(processed_path).context("Failed to load processed region data") + fn load_region( + region_cache: &mut LruCache>, + processed_path: &Path, + ) -> Result> { + if let Some(region) = region_cache.get(processed_path) { + return Ok(region.clone()); + } + + let region: Rc = + storage::read(processed_path).context("Failed to load processed region data")?; + region_cache.put(processed_path.to_owned(), region.clone()); + + Ok(region) } fn load_region_group( + region_cache: &mut LruCache>, processed_paths: RegionGroup, - ) -> Result>> { - processed_paths.try_map(|path| Self::load_region(&path)) + ) -> Result>> { + processed_paths.try_map(|path| Self::load_region(region_cache, &path)) } fn block_color_at( - region_group: &RegionGroup>, + region_group: &RegionGroup>, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, @@ -141,7 +156,7 @@ impl<'a> TileRenderer<'a> { fn render_chunk( image: &mut image::RgbaImage, - region_group: &RegionGroup>, + region_group: &RegionGroup>, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, ) { @@ -164,7 +179,7 @@ impl<'a> TileRenderer<'a> { fn render_region( image: &mut image::RgbaImage, - region_group: &RegionGroup>, + region_group: &RegionGroup>, ) { for (coords, chunk) in region_group.center().chunks.iter() { let Some(chunk) = chunk else { @@ -200,7 +215,11 @@ impl<'a> TileRenderer<'a> { Ok((paths, max_timestamp)) } - fn render_tile(&self, coords: TileCoords) -> Result<()> { + fn render_tile( + &self, + region_cache: &mut LruCache>, + coords: TileCoords, + ) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let (processed_paths, processed_timestamp) = self.processed_sources(coords)?; @@ -227,7 +246,7 @@ impl<'a> TileRenderer<'a> { .display(), ); - let region_group = Self::load_region_group(processed_paths) + let region_group = Self::load_region_group(region_cache, processed_paths) .with_context(|| format!("Region {:?} from previous step must be loadable", coords))?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion_group); @@ -247,8 +266,10 @@ impl<'a> TileRenderer<'a> { pub fn run(self, regions: &[TileCoords]) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; + let mut region_cache = LruCache::new(NonZeroUsize::new(12).unwrap()); + for &coords in regions { - if let Err(err) = self.render_tile(coords) { + if let Err(err) = self.render_tile(&mut region_cache, coords) { eprintln!("Failed to render tile {:?}: {:?}", coords, err); } } From b80d9ee420290db2437d1632668a37ee8d741241 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 5 Aug 2023 23:56:37 +0200 Subject: [PATCH 218/460] minedmap/tile_renderer: make biome HashMap more efficient Using a u32 instead of a tuple makes the hash calculation faster, because the fields don't have to be hashed separately. --- src/bin/minedmap/tile_renderer.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index abacffd..e9a4a13 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -103,6 +103,10 @@ impl<'a> TileRenderer<'a> { chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, ) -> Option { + 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 + } + const SMOOTH: [[f32; 3]; 3] = [[41.0, 26.0, 7.0], [26.0, 16.0, 4.0], [7.0, 4.0, 1.0]]; const X: isize = SMOOTH[0].len() as isize - 1; const Z: isize = SMOOTH.len() as isize - 1; @@ -114,7 +118,7 @@ impl<'a> TileRenderer<'a> { return Some(block_color(block, None, depth.0 as f32)); } - let mut weights = rustc_hash::FxHashMap::<(i8, i8, u16), f32>::default(); + let mut weights = rustc_hash::FxHashMap::::default(); for dz in -Z..=Z { for dx in -X..=X { let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()]; @@ -132,7 +136,9 @@ impl<'a> TileRenderer<'a> { continue; }; - *weights.entry(biome).or_default() += w; + let value = weights.entry(biome_key(biome)).or_default(); + value.0 = biome; + value.1 += w; } } @@ -143,7 +149,7 @@ impl<'a> TileRenderer<'a> { let mut color = Vec3::ZERO; let mut total = 0.0; - for ((region_x, region_z, index), w) in weights { + 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())?; From 21035a1f7f37a35c488face88ec04db4e087ba55 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 6 Aug 2023 11:26:08 +0200 Subject: [PATCH 219/460] Move coord offset to new util module, make more efficient div_floor_mod() generates inefficient code. For power-of-2 divisors, shift and mask can be used instead. --- src/bin/minedmap/tile_renderer.rs | 59 +--------------------- src/lib.rs | 1 + src/types.rs | 6 ++- src/util.rs | 84 +++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 60 deletions(-) create mode 100644 src/util.rs diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index e9a4a13..def56b4 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -8,39 +8,16 @@ use std::{ use anyhow::{Context, Result}; use glam::Vec3; use lru::LruCache; -use num_integer::div_mod_floor; use minedmap::{ io::{fs, storage}, resource::{block_color, needs_biome}, types::*, + util::coord_offset, }; use super::{common::*, region_group::RegionGroup}; -/// Offsets a chunk and block coordinate pair by a number of blocks -/// -/// As the new coordinate may end up in a different region, a region offset -/// is returned together with the new chunk and block coordinates. -fn coord_offset( - chunk: ChunkCoord, - block: BlockCoord, - offset: i32, -) -> (i8, ChunkCoord, BlockCoord) { - const CHUNKS: i32 = CHUNKS_PER_REGION as i32; - const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32; - let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset; - let (region_chunk, block) = div_mod_floor(coord, BLOCKS); - let (region, chunk) = div_mod_floor(region_chunk, CHUNKS); - ( - region - .try_into() - .expect("the region coordinate should be in the valid range"), - ChunkCoord::new(chunk), - BlockCoord::new(block), - ) -} - fn biome_at( region_group: &RegionGroup>, chunk: ChunkCoords, @@ -283,37 +260,3 @@ impl<'a> TileRenderer<'a> { Ok(()) } } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_coord_offset() { - const CHUNKS: i32 = CHUNKS_PER_REGION as i32; - const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32; - - for chunk in ChunkX::iter() { - for block in BlockX::iter() { - assert_eq!(coord_offset(chunk, block, 0), (0, chunk, block)); - assert_eq!( - coord_offset(chunk, block, -(CHUNKS * BLOCKS)), - (-1, chunk, block) - ); - assert_eq!( - coord_offset(chunk, block, CHUNKS * BLOCKS), - (1, chunk, block) - ); - - for offset in -(CHUNKS * BLOCKS)..(CHUNKS * BLOCKS) { - let (region2, chunk2, block2) = coord_offset(chunk, block, offset); - assert!((-1..=1).contains(®ion2)); - let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset; - let coord2 = - ((region2 as i32 * CHUNKS) + chunk2.0 as i32) * BLOCKS + block2.0 as i32; - assert_eq!(coord2, coord); - } - } - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 8342ba8..f46a9d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod io; pub mod resource; pub mod types; +pub mod util; pub mod world; diff --git a/src/types.rs b/src/types.rs index 465dd2a..a28583d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -47,7 +47,8 @@ macro_rules! coord_type { }; } -pub const BLOCKS_PER_CHUNK: usize = 16; +pub const BLOCK_BITS: u8 = 4; +pub const BLOCKS_PER_CHUNK: usize = 1 << BLOCK_BITS; coord_type!(BlockCoord, BLOCKS_PER_CHUNK); /// A block X coordinate relative to a chunk @@ -136,7 +137,8 @@ impl Debug for SectionBlockCoords { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct SectionY(pub i32); -pub const CHUNKS_PER_REGION: usize = 32; +pub const CHUNK_BITS: u8 = 5; +pub const CHUNKS_PER_REGION: usize = 1 << CHUNK_BITS; coord_type!(ChunkCoord, CHUNKS_PER_REGION); /// A chunk X coordinate relative to a region diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..436c070 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,84 @@ +use crate::types::*; + +pub trait ShiftMask: Sized { + type MaskedOutput; + + /// Apply a right shift to a value, and return both the result and the + /// bytes that were shifted out + fn shift_mask(self, shift: u8) -> (Self, Self::MaskedOutput); +} + +impl ShiftMask for u32 { + type MaskedOutput = u32; + + fn shift_mask(self, shift: u8) -> (u32, u32) { + let mask = (1 << shift) - 1; + (self >> shift, self & mask) + } +} + +impl ShiftMask for i32 { + type MaskedOutput = u32; + + #[inline] + fn shift_mask(self, shift: u8) -> (i32, u32) { + let mask = (1 << shift) - 1; + (self >> shift, (self as u32) & mask) + } +} + +/// Offsets a chunk and block coordinate pair by a number of blocks +/// +/// As the new coordinate may end up in a different region, a region offset +/// is returned together with the new chunk and block coordinates. +#[inline] +pub fn coord_offset( + chunk: ChunkCoord, + block: BlockCoord, + offset: i32, +) -> (i8, ChunkCoord, BlockCoord) { + let coord = ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32) + offset; + let (region_chunk, block) = coord.shift_mask(BLOCK_BITS); + let (region, chunk) = region_chunk.shift_mask(CHUNK_BITS); + ( + region + .try_into() + .expect("the region coordinate should be in the valid range"), + ChunkCoord::new(chunk), + BlockCoord::new(block), + ) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_coord_offset() { + const CHUNKS: i32 = CHUNKS_PER_REGION as i32; + const BLOCKS: i32 = BLOCKS_PER_CHUNK as i32; + + for chunk in ChunkX::iter() { + for block in BlockX::iter() { + assert_eq!(coord_offset(chunk, block, 0), (0, chunk, block)); + assert_eq!( + coord_offset(chunk, block, -(CHUNKS * BLOCKS)), + (-1, chunk, block) + ); + assert_eq!( + coord_offset(chunk, block, CHUNKS * BLOCKS), + (1, chunk, block) + ); + + for offset in -(CHUNKS * BLOCKS)..(CHUNKS * BLOCKS) { + let (region2, chunk2, block2) = coord_offset(chunk, block, offset); + assert!((-1..=1).contains(®ion2)); + let coord = chunk.0 as i32 * BLOCKS + block.0 as i32 + offset; + let coord2 = + ((region2 as i32 * CHUNKS) + chunk2.0 as i32) * BLOCKS + block2.0 as i32; + assert_eq!(coord2, coord); + } + } + } + } +} From 9c4161f6885e312a06282750bec294283b26b857 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 6 Aug 2023 12:32:14 +0200 Subject: [PATCH 220/460] util: turn range check into debug_assert!() More performance optimization. --- src/util.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/util.rs b/src/util.rs index 436c070..43245ca 100644 --- a/src/util.rs +++ b/src/util.rs @@ -40,13 +40,8 @@ pub fn coord_offset( let coord = ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32) + offset; let (region_chunk, block) = coord.shift_mask(BLOCK_BITS); let (region, chunk) = region_chunk.shift_mask(CHUNK_BITS); - ( - region - .try_into() - .expect("the region coordinate should be in the valid range"), - ChunkCoord::new(chunk), - BlockCoord::new(block), - ) + debug_assert!(i8::try_from(region).is_ok()); + (region as i8, ChunkCoord::new(chunk), BlockCoord::new(block)) } #[cfg(test)] From 4a824680a9629ac365478d94f0418c7a16105981 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 Aug 2023 12:16:11 +0200 Subject: [PATCH 221/460] Update dependencies --- Cargo.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 839c9ae..9e73977 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,9 +66,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" dependencies = [ "anstyle", "windows-sys", @@ -103,9 +103,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bytemuck" @@ -121,9 +121,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" dependencies = [ "jobserver", "libc", @@ -143,9 +143,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" dependencies = [ "clap_builder", "clap_derive", @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" dependencies = [ "anstream", "anstyle", @@ -327,9 +327,9 @@ checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "image" -version = "0.24.6" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" dependencies = [ "bytemuck", "byteorder", @@ -530,11 +530,11 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.6" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -549,9 +549,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.181" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3e73c93c3240c0bda063c239298e633114c69a888c3e37ca8bb33f343e9890" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.181" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be02f6cb0cd3a5ec20bbcfbcbd749f57daddb1a0882dc2e46a6c236c90b977ed" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", From d5ac38ed9bb3454089f7fe4a4dc4a032aac39220 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 Aug 2023 21:51:12 +0200 Subject: [PATCH 222/460] util: split to_flat_coord() and from_flat_coord() out of coord_offset() --- src/util.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/util.rs b/src/util.rs index 43245ca..b4fdefe 100644 --- a/src/util.rs +++ b/src/util.rs @@ -27,6 +27,23 @@ impl ShiftMask for i32 { } } +#[inline] +pub fn to_flat_coord( + region: i8, + chunk: ChunkCoord, + block: BlockCoord, +) -> i32 { + (region as i32) << (BLOCK_BITS + CHUNK_BITS) | ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32) +} + +#[inline] +pub fn from_flat_coord(coord: i32) -> (i8, ChunkCoord, BlockCoord) { + let (region_chunk, block) = coord.shift_mask(BLOCK_BITS); + let (region, chunk) = region_chunk.shift_mask(CHUNK_BITS); + debug_assert!(i8::try_from(region).is_ok()); + (region as i8, ChunkCoord::new(chunk), BlockCoord::new(block)) +} + /// Offsets a chunk and block coordinate pair by a number of blocks /// /// As the new coordinate may end up in a different region, a region offset @@ -37,11 +54,7 @@ pub fn coord_offset( block: BlockCoord, offset: i32, ) -> (i8, ChunkCoord, BlockCoord) { - let coord = ((chunk.0 as i32) << BLOCK_BITS | block.0 as i32) + offset; - let (region_chunk, block) = coord.shift_mask(BLOCK_BITS); - let (region, chunk) = region_chunk.shift_mask(CHUNK_BITS); - debug_assert!(i8::try_from(region).is_ok()); - (region as i8, ChunkCoord::new(chunk), BlockCoord::new(block)) + from_flat_coord(to_flat_coord(0, chunk, block) + offset) } #[cfg(test)] From c1260a63b5ce859bfa101c93bc5ce4fc1a01e0e9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 14 Aug 2023 14:27:52 +0200 Subject: [PATCH 223/460] minedmap: separate collection for region list from preprocessing Preparation for parallel processing, as well as a fix for regions missing from later steps when the initial processing failed (rather than using the processed data from a previous run). --- src/bin/minedmap/common.rs | 5 ++ src/bin/minedmap/main.rs | 8 +--- src/bin/minedmap/region_processor.rs | 72 ++++++++++++++-------------- 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 44c7ae4..a063bf8 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -85,6 +85,11 @@ impl Config { } } + pub fn region_path(&self, coords: TileCoords) -> PathBuf { + let filename = coord_filename(coords, "mca"); + [&self.region_dir, Path::new(&filename)].iter().collect() + } + pub fn processed_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "bin"); [&self.processed_dir, Path::new(&filename)].iter().collect() diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 838728c..8d3bbea 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; use anyhow::Result; use clap::Parser; -use common::{Config, TileCoords}; +use common::Config; use metadata_writer::MetadataWriter; use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; @@ -28,11 +28,7 @@ fn main() -> Result<()> { let args = Args::parse(); let config = Config::new(args); - let mut regions = RegionProcessor::new(&config).run()?; - - // 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 })); - + let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config).run(®ions)?; let tiles = TileMipmapper::new(&config).run(®ions)?; MetadataWriter::new(&config).run(tiles)?; diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 34c9555..639dac7 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,4 +1,4 @@ -use std::{path::Path, time::SystemTime}; +use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; @@ -16,9 +16,8 @@ use minedmap::{ use super::common::*; /// Parses a filename in the format r.X.Z.mca into the contained X and Z values -fn parse_region_filename(path: &Path) -> Option { - let file_name = path.file_name()?.to_str()?; - let parts: Vec<_> = file_name.split('.').collect(); +fn parse_region_filename(file_name: &OsStr) -> Option { + let parts: Vec<_> = file_name.to_str()?.split('.').collect(); let &["r", x, z, "mca"] = parts.as_slice() else { return None; }; @@ -45,6 +44,29 @@ impl<'a> RegionProcessor<'a> { } } + fn collect_regions(&self) -> Result> { + Ok(self + .config + .region_dir + .read_dir() + .with_context(|| { + format!( + "Failed to read directory {}", + self.config.region_dir.display() + ) + })? + .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) + ) + }) + .filter_map(|entry| parse_region_filename(&entry.file_name())) + .collect()) + } + /// Processes a single chunk fn process_chunk( &self, @@ -91,13 +113,14 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single region file - fn process_region(&self, path: &Path, coords: TileCoords) -> Result<()> { + fn process_region(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); - let input_timestamp = fs::modified_timestamp(path)?; + let path = self.config.region_path(coords); + let input_timestamp = fs::modified_timestamp(&path)?; let output_path = self.config.processed_path(coords); let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); @@ -152,41 +175,20 @@ impl<'a> RegionProcessor<'a> { /// /// Returns a list of the coordinates of all processed regions pub fn run(self) -> Result> { - let read_dir = self.config.region_dir.read_dir().with_context(|| { - format!( - "Failed to read directory {}", - self.config.region_dir.display() - ) - })?; + let mut regions = self.collect_regions()?; + + // 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 })); fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; - let mut ret = Vec::new(); - - for entry in read_dir.filter_map(|entry| entry.ok()).filter(|entry| { - // We are only interested in regular files - entry - .file_type() - .map(|file_type| file_type.is_file()) - .unwrap_or_default() - }) { - let path = entry.path(); - let Some(coords) = parse_region_filename(&path) else { - continue; - }; - - if let Err(err) = self.process_region(&path, coords) { - eprintln!( - "Failed to process region {}: {:?}", - path.file_name().unwrap_or_default().to_string_lossy(), - err, - ); + for &coords in ®ions { + if let Err(err) = self.process_region(coords) { + eprintln!("Failed to process region {:?}: {:?}", coords, err); } - - ret.push(coords); } - Ok(ret) + Ok(regions) } } From 78fe1ec50efc3c4f912e5e28f1590e1c2b84b4e2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 14 Aug 2023 15:48:05 +0200 Subject: [PATCH 224/460] minedmap: add support for parallel processing For now, only RegionProcessor and TileMipmapper are run in parallel. --- Cargo.lock | 151 +++++++++++++++++++++++++++ Cargo.toml | 3 + src/bin/minedmap/common.rs | 12 ++- src/bin/minedmap/main.rs | 19 +++- src/bin/minedmap/region_processor.rs | 7 +- src/bin/minedmap/tile_mipmapper.rs | 10 +- 6 files changed, 191 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e73977..c6cae9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,6 +212,49 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "either" version = "1.9.0" @@ -297,6 +340,43 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "glam" version = "0.24.1" @@ -416,6 +496,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "minedmap" version = "0.1.0" @@ -427,12 +516,15 @@ dependencies = [ "enumflags2", "fastnbt", "flate2", + "futures-util", "glam", "image", "indexmap", "itertools", "lru", "num-integer", + "num_cpus", + "rayon", "rustc-hash", "serde", "serde_json", @@ -479,12 +571,34 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "pin-project-lite" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.27" @@ -522,6 +636,28 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -547,6 +683,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.183" @@ -593,6 +735,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index 5d74ce8..c6013ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,12 +15,15 @@ clap = { version = "4.1.4", features = ["derive"] } enumflags2 = "0.7.5" fastnbt = "2.3.2" flate2 = "1.0.25" +futures-util = "0.3.28" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } itertools = "0.11.0" lru = "0.11.0" num-integer = "0.1.45" +num_cpus = "1.16.0" +rayon = "1.7.0" rustc-hash = "1.1.0" serde = { version = "1.0.152", features = ["rc"] } serde_json = "1.0.99" diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index a063bf8..c0c4c8c 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -52,6 +52,7 @@ pub struct ProcessedRegion { } pub struct Config { + pub num_threads: usize, pub region_dir: PathBuf, pub processed_dir: PathBuf, pub output_dir: PathBuf, @@ -70,16 +71,23 @@ pub enum TileKind { } impl Config { - pub fn new(args: super::Args) -> Self { + pub fn new(args: &super::Args) -> Self { + let num_threads = match args.jobs { + Some(0) => num_cpus::get(), + Some(threads) => threads, + None => 1, + }; + let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); let processed_dir = [&args.output_dir, Path::new("processed")].iter().collect(); let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect(); let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); Config { + num_threads, region_dir, processed_dir, - output_dir: args.output_dir, + output_dir: args.output_dir.clone(), level_dat_path, metadata_path, } diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 8d3bbea..55158ed 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -7,7 +7,7 @@ mod tile_renderer; use std::path::PathBuf; -use anyhow::Result; +use anyhow::{Context, Result}; use clap::Parser; use common::Config; @@ -18,15 +18,30 @@ use tile_renderer::TileRenderer; #[derive(Debug, Parser)] pub struct Args { + /// Number of parallel threads to use for processing + /// + /// If not given, only a single thread is used. Pass 0 to + /// use one thread per logical CPU core. + #[arg(short, long)] + pub jobs: Option, /// Minecraft save directory pub input_dir: PathBuf, /// MinedMap data directory pub output_dir: PathBuf, } +fn setup_threads(num_threads: usize) -> Result<()> { + rayon::ThreadPoolBuilder::new() + .num_threads(num_threads) + .build_global() + .context("Failed to configure thread pool") +} + fn main() -> Result<()> { let args = Args::parse(); - let config = Config::new(args); + let config = Config::new(&args); + + setup_threads(config.num_threads)?; let regions = RegionProcessor::new(&config).run()?; TileRenderer::new(&config).run(®ions)?; diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 639dac7..6aa2cb4 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,8 +1,9 @@ use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; - use indexmap::IndexSet; +use rayon::prelude::*; + use minedmap::{ io::{fs, storage}, resource::{self, Biome}, @@ -183,11 +184,11 @@ impl<'a> RegionProcessor<'a> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; - for &coords in ®ions { + regions.par_iter().for_each(|&coords| { if let Err(err) = self.process_region(coords) { eprintln!("Failed to process region {:?}: {:?}", coords, err); } - } + }); Ok(regions) } diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 40add3a..2c1e9d6 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -1,4 +1,5 @@ use anyhow::{Context, Result}; +use rayon::prelude::*; use minedmap::{io::fs, types::*}; @@ -151,8 +152,8 @@ impl<'a> TileMipmapper<'a> { let next = Self::map_coords(prev); - for (&z, xs) in &next.0 { - for &x in xs { + next.0.par_iter().try_for_each(|(&z, xs)| { + xs.par_iter().try_for_each(|&x| { let coords = TileCoords { x, z }; self.render_mipmap::>(TileKind::Map, level, coords, prev)?; self.render_mipmap::>( @@ -161,8 +162,9 @@ impl<'a> TileMipmapper<'a> { coords, prev, )?; - } - } + anyhow::Ok(()) + }) + })?; tile_stack.push(next); } From dcc9e6e794c46efb9b0fa368d3b771f55857520b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 14 Aug 2023 22:32:06 +0200 Subject: [PATCH 225/460] minedmap/region_group: add async map functions --- src/bin/minedmap/region_group.rs | 43 +++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index aa7088c..1f87b1c 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -1,6 +1,7 @@ -use std::iter; +use std::{future::Future, iter}; use anyhow::Result; +use futures_util::future::OptionFuture; /// A generic array of 3x3 elements /// @@ -70,6 +71,46 @@ impl RegionGroup { Ok(RegionGroup { center, neighs }) } + #[allow(dead_code)] + pub async fn async_map(self, mut f: F) -> RegionGroup + where + Fut: Future, + F: FnMut(T) -> Fut, + { + let center = f(self.center); + let neighs = futures_util::future::join_all( + self.neighs + .map(|entry| OptionFuture::from(entry.map(&mut f))), + ); + let (center, neighs) = futures_util::join!(center, neighs); + RegionGroup { + center, + neighs: <[Option<_>; 9]>::try_from(neighs).ok().unwrap(), + } + } + + pub async fn async_try_map(self, mut f: F) -> Result> + where + Fut: Future>, + F: FnMut(T) -> Fut, + { + let center = f(self.center); + let neighs = futures_util::future::join_all( + self.neighs + .map(|entry| OptionFuture::from(entry.map(&mut f))), + ); + let (center, neighs) = futures_util::join!(center, neighs); + let center = center?; + + let neighs: Vec<_> = neighs + .into_iter() + .map(|entry| entry.and_then(Result::ok)) + .collect(); + let neighs = <[Option<_>; 9]>::try_from(neighs).ok().unwrap(); + + Ok(RegionGroup { center, neighs }) + } + pub fn iter(&self) -> impl Iterator { iter::once(&self.center).chain(self.neighs.iter().filter_map(Option::as_ref)) } From b5980b82af95443a4a7f8bfdd73d7015535f93c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 14 Aug 2023 21:59:16 +0200 Subject: [PATCH 226/460] minedmap/tile_renderer: async region cache Prepare for sharing the region cache between multiple threads by making lookup/load async. --- Cargo.lock | 111 ++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/bin/minedmap/main.rs | 6 +- src/bin/minedmap/tile_renderer.rs | 86 +++++++++++++---------- 4 files changed, 165 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6cae9f..fcf88f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -86,6 +95,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bincode" version = "1.3.3" @@ -377,6 +401,12 @@ dependencies = [ "slab", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "glam" version = "0.24.1" @@ -487,6 +517,16 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "lru" version = "0.11.0" @@ -496,6 +536,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "memoffset" version = "0.9.0" @@ -528,6 +574,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", + "tokio", "zstd", ] @@ -581,12 +628,44 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "pin-project-lite" version = "0.2.12" @@ -658,6 +737,21 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -744,6 +838,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + [[package]] name = "strsim" version = "0.10.0" @@ -761,6 +861,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tokio" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" +dependencies = [ + "backtrace", + "parking_lot", + "pin-project-lite", +] + [[package]] name = "unicode-ident" version = "1.0.11" diff --git a/Cargo.toml b/Cargo.toml index c6013ac..111ee92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ rayon = "1.7.0" rustc-hash = "1.1.0" serde = { version = "1.0.152", features = ["rc"] } serde_json = "1.0.99" +tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } zstd = "0.12.3" [features] diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 55158ed..05a0a38 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -43,8 +43,12 @@ fn main() -> Result<()> { setup_threads(config.num_threads)?; + let rt = tokio::runtime::Builder::new_current_thread() + .build() + .unwrap(); + let regions = RegionProcessor::new(&config).run()?; - TileRenderer::new(&config).run(®ions)?; + TileRenderer::new(&config, &rt).run(®ions)?; let tiles = TileMipmapper::new(&config).run(®ions)?; MetadataWriter::new(&config).run(tiles)?; diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index def56b4..3596e0a 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,13 +1,14 @@ use std::{ num::NonZeroUsize, - path::{Path, PathBuf}, - rc::Rc, + path::PathBuf, + sync::{Arc, Mutex}, time::SystemTime, }; use anyhow::{Context, Result}; use glam::Vec3; use lru::LruCache; +use tokio::sync::OnceCell; use minedmap::{ io::{fs, storage}, @@ -18,8 +19,10 @@ use minedmap::{ use super::{common::*, region_group::RegionGroup}; +type RegionRef = Arc; + fn biome_at( - region_group: &RegionGroup>, + region_group: &RegionGroup, chunk: ChunkCoords, block: LayerBlockCoords, dx: i32, @@ -45,37 +48,51 @@ fn biome_at( pub struct TileRenderer<'a> { config: &'a Config, + rt: &'a tokio::runtime::Runtime, + region_cache: Mutex>>>, } impl<'a> TileRenderer<'a> { - pub fn new(config: &'a Config) -> Self { - TileRenderer { config } - } - - fn load_region( - region_cache: &mut LruCache>, - processed_path: &Path, - ) -> Result> { - if let Some(region) = region_cache.get(processed_path) { - return Ok(region.clone()); + pub fn new(config: &'a Config, rt: &'a tokio::runtime::Runtime) -> Self { + let region_cache = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); + TileRenderer { + config, + rt, + region_cache, } - - let region: Rc = - storage::read(processed_path).context("Failed to load processed region data")?; - region_cache.put(processed_path.to_owned(), region.clone()); - - Ok(region) } - fn load_region_group( - region_cache: &mut LruCache>, + async fn load_region(&self, processed_path: PathBuf) -> Result { + let region_loader = { + let mut region_cache = self.region_cache.lock().unwrap(); + if let Some(region_loader) = region_cache.get(&processed_path) { + Arc::clone(region_loader) + } else { + let region_loader = Default::default(); + region_cache.put(processed_path.clone(), Arc::clone(®ion_loader)); + region_loader + } + }; + + region_loader + .get_or_try_init(|| async { + storage::read(&processed_path).context("Failed to load processed region data") + }) + .await + .cloned() + } + + async fn load_region_group( + &self, processed_paths: RegionGroup, - ) -> Result>> { - processed_paths.try_map(|path| Self::load_region(region_cache, &path)) + ) -> Result> { + processed_paths + .async_try_map(move |path| self.load_region(path)) + .await } fn block_color_at( - region_group: &RegionGroup>, + region_group: &RegionGroup, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, @@ -139,7 +156,7 @@ impl<'a> TileRenderer<'a> { fn render_chunk( image: &mut image::RgbaImage, - region_group: &RegionGroup>, + region_group: &RegionGroup, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, ) { @@ -160,10 +177,7 @@ impl<'a> TileRenderer<'a> { overlay_chunk(image, &chunk_image, chunk_coords); } - fn render_region( - image: &mut image::RgbaImage, - region_group: &RegionGroup>, - ) { + fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { for (coords, chunk) in region_group.center().chunks.iter() { let Some(chunk) = chunk else { continue; @@ -198,11 +212,7 @@ impl<'a> TileRenderer<'a> { Ok((paths, max_timestamp)) } - fn render_tile( - &self, - region_cache: &mut LruCache>, - coords: TileCoords, - ) -> Result<()> { + fn render_tile(&self, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let (processed_paths, processed_timestamp) = self.processed_sources(coords)?; @@ -229,7 +239,9 @@ impl<'a> TileRenderer<'a> { .display(), ); - let region_group = Self::load_region_group(region_cache, processed_paths) + let region_group = self + .rt + .block_on(self.load_region_group(processed_paths)) .with_context(|| format!("Region {:?} from previous step must be loadable", coords))?; let mut image = image::RgbaImage::new(N, N); Self::render_region(&mut image, ®ion_group); @@ -249,10 +261,8 @@ impl<'a> TileRenderer<'a> { pub fn run(self, regions: &[TileCoords]) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; - let mut region_cache = LruCache::new(NonZeroUsize::new(12).unwrap()); - for &coords in regions { - if let Err(err) = self.render_tile(&mut region_cache, coords) { + if let Err(err) = self.render_tile(coords) { eprintln!("Failed to render tile {:?}: {:?}", coords, err); } } From 155171803df021fd3dd5cff25c608ac95d1bf7a9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 14 Aug 2023 22:40:20 +0200 Subject: [PATCH 227/460] minedmap/tile_renderer: parallel processing --- src/bin/minedmap/tile_renderer.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 3596e0a..30276a8 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -8,6 +8,7 @@ use std::{ use anyhow::{Context, Result}; use glam::Vec3; use lru::LruCache; +use rayon::prelude::*; use tokio::sync::OnceCell; use minedmap::{ @@ -54,7 +55,9 @@ pub struct TileRenderer<'a> { impl<'a> TileRenderer<'a> { pub fn new(config: &'a Config, rt: &'a tokio::runtime::Runtime) -> Self { - let region_cache = Mutex::new(LruCache::new(NonZeroUsize::new(12).unwrap())); + let region_cache = Mutex::new(LruCache::new( + NonZeroUsize::new(6 + 6 * config.num_threads).unwrap(), + )); TileRenderer { config, rt, @@ -261,11 +264,12 @@ impl<'a> TileRenderer<'a> { pub fn run(self, regions: &[TileCoords]) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; - for &coords in regions { + // Use par_bridge to process items in order (for better use of region cache) + regions.iter().par_bridge().for_each(|&coords| { if let Err(err) = self.render_tile(coords) { eprintln!("Failed to render tile {:?}: {:?}", coords, err); } - } + }); Ok(()) } From 6a82fcc9b48e0bf4efd3dc679c59a008937130a1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 15 Aug 2023 18:31:53 +0200 Subject: [PATCH 228/460] minedmap/tile_renderer: terminate on errors Only the processing step may fail for individual tiles (when a region is currently being saved when attempting to process it), the other steps should never fail. --- src/bin/minedmap/tile_renderer.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 30276a8..a7c3121 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -265,11 +265,10 @@ impl<'a> TileRenderer<'a> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; // Use par_bridge to process items in order (for better use of region cache) - regions.iter().par_bridge().for_each(|&coords| { - if let Err(err) = self.render_tile(coords) { - eprintln!("Failed to render tile {:?}: {:?}", coords, err); - } - }); + regions.iter().par_bridge().try_for_each(|&coords| { + self.render_tile(coords) + .with_context(|| format!("Failed to render tile {:?}", coords)) + })?; Ok(()) } From 722fe00d77763f0db99e5d566d61d7ed0c86becd Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 15 Aug 2023 18:45:38 +0200 Subject: [PATCH 229/460] minedmap: move inputs to processing steps from run() to new() --- src/bin/minedmap/main.rs | 6 +++--- src/bin/minedmap/metadata_writer.rs | 17 +++++++++-------- src/bin/minedmap/tile_mipmapper.rs | 9 +++++---- src/bin/minedmap/tile_renderer.rs | 12 +++++++++--- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 05a0a38..ebeae87 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -48,9 +48,9 @@ fn main() -> Result<()> { .unwrap(); let regions = RegionProcessor::new(&config).run()?; - TileRenderer::new(&config, &rt).run(®ions)?; - let tiles = TileMipmapper::new(&config).run(®ions)?; - MetadataWriter::new(&config).run(tiles)?; + TileRenderer::new(&config, &rt, ®ions).run()?; + let tiles = TileMipmapper::new(&config, ®ions).run()?; + MetadataWriter::new(&config, &tiles).run()?; Ok(()) } diff --git a/src/bin/minedmap/metadata_writer.rs b/src/bin/minedmap/metadata_writer.rs index 437152a..3862362 100644 --- a/src/bin/minedmap/metadata_writer.rs +++ b/src/bin/minedmap/metadata_writer.rs @@ -4,10 +4,6 @@ use serde::Serialize; use super::common::*; -pub struct MetadataWriter<'a> { - config: &'a Config, -} - #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Bounds { @@ -35,9 +31,14 @@ struct Metadata<'t> { spawn: Spawn, } +pub struct MetadataWriter<'a> { + config: &'a Config, + tiles: &'a [TileCoordMap], +} + impl<'a> MetadataWriter<'a> { - pub fn new(config: &'a Config) -> Self { - MetadataWriter { config } + pub fn new(config: &'a Config, tiles: &'a [TileCoordMap]) -> Self { + MetadataWriter { config, tiles } } fn mipmap_entry(regions: &TileCoordMap) -> Mipmap { @@ -87,7 +88,7 @@ impl<'a> MetadataWriter<'a> { } } - pub fn run(&self, tiles: Vec) -> Result<()> { + pub fn run(self) -> Result<()> { let level_dat = self.read_level_dat()?; let mut metadata = Metadata { @@ -95,7 +96,7 @@ impl<'a> MetadataWriter<'a> { spawn: Self::spawn(&level_dat), }; - for tile_map in tiles.iter() { + for tile_map in self.tiles.iter() { metadata.mipmaps.push(Self::mipmap_entry(tile_map)); } diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 2c1e9d6..4a8cf63 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -7,11 +7,12 @@ use super::common::*; pub struct TileMipmapper<'a> { config: &'a Config, + regions: &'a [TileCoords], } impl<'a> TileMipmapper<'a> { - pub fn new(config: &'a Config) -> Self { - TileMipmapper { config } + pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self { + TileMipmapper { config, regions } } fn done(tiles: &TileCoordMap) -> bool { @@ -129,11 +130,11 @@ impl<'a> TileMipmapper<'a> { }) } - pub fn run(self, tiles: &[TileCoords]) -> Result> { + pub fn run(self) -> Result> { let mut tile_stack = { let mut tile_map = TileCoordMap::default(); - for &TileCoords { x, z } in tiles { + for &TileCoords { x, z } in self.regions { tile_map.0.entry(z).or_default().insert(x); } diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index a7c3121..048cf77 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -50,17 +50,23 @@ fn biome_at( pub struct TileRenderer<'a> { config: &'a Config, rt: &'a tokio::runtime::Runtime, + regions: &'a [TileCoords], region_cache: Mutex>>>, } impl<'a> TileRenderer<'a> { - pub fn new(config: &'a Config, rt: &'a tokio::runtime::Runtime) -> Self { + pub fn new( + config: &'a Config, + rt: &'a tokio::runtime::Runtime, + regions: &'a [TileCoords], + ) -> Self { let region_cache = Mutex::new(LruCache::new( NonZeroUsize::new(6 + 6 * config.num_threads).unwrap(), )); TileRenderer { config, rt, + regions, region_cache, } } @@ -261,11 +267,11 @@ impl<'a> TileRenderer<'a> { ) } - pub fn run(self, regions: &[TileCoords]) -> Result<()> { + pub fn run(self) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; // Use par_bridge to process items in order (for better use of region cache) - regions.iter().par_bridge().try_for_each(|&coords| { + self.regions.iter().par_bridge().try_for_each(|&coords| { self.render_tile(coords) .with_context(|| format!("Failed to render tile {:?}", coords)) })?; From 427a992897781bd0fbcd7085227fdd86788936c4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 15 Aug 2023 20:48:41 +0200 Subject: [PATCH 230/460] minedmap/tile_renderer: keep HashSet of populated regions Rather than attemping to read the file metadata, it's more elegant to check whether a tile is supposed to be available first. --- src/bin/minedmap/common.rs | 2 +- src/bin/minedmap/region_group.rs | 23 +++++++++++------------ src/bin/minedmap/tile_renderer.rs | 7 ++++++- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index c0c4c8c..48cebf8 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -12,7 +12,7 @@ use minedmap::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer} // Increase to force regeneration of all output files pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TileCoords { pub x: i32, pub z: i32, diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index 1f87b1c..be46511 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -16,25 +16,24 @@ pub struct RegionGroup { } impl RegionGroup { - pub fn new(f: F) -> Result + pub fn new(f: F) -> Self where - F: Fn(i8, i8) -> Result, + F: Fn(i8, i8) -> Option, { RegionGroup { - center: (0, 0), + center: f(0, 0).expect("Center element of RegionGroup must not be None"), neighs: [ - Some((-1, -1)), - Some((-1, 0)), - Some((-1, 1)), - Some((0, -1)), + f(-1, -1), + f(-1, 0), + f(-1, 1), + f(0, -1), None, - Some((0, 1)), - Some((1, -1)), - Some((1, 0)), - Some((1, 1)), + f(0, 1), + f(1, -1), + f(1, 0), + f(1, 1), ], } - .try_map(|(x, z)| f(x, z)) } pub fn center(&self) -> &T { diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 048cf77..bc59b23 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -51,6 +51,7 @@ pub struct TileRenderer<'a> { config: &'a Config, rt: &'a tokio::runtime::Runtime, regions: &'a [TileCoords], + region_set: rustc_hash::FxHashSet, region_cache: Mutex>>>, } @@ -63,10 +64,12 @@ impl<'a> TileRenderer<'a> { let region_cache = Mutex::new(LruCache::new( NonZeroUsize::new(6 + 6 * config.num_threads).unwrap(), )); + let region_set = regions.iter().copied().collect(); TileRenderer { config, rt, regions, + region_set, region_cache, } } @@ -204,11 +207,13 @@ impl<'a> TileRenderer<'a> { fn processed_sources(&self, coords: TileCoords) -> Result<(RegionGroup, SystemTime)> { let sources = RegionGroup::new(|x, z| { - self.processed_source(TileCoords { + Some(TileCoords { x: coords.x + (x as i32), z: coords.z + (z as i32), }) + .filter(|entry| self.region_set.contains(entry)) }) + .try_map(|entry| self.processed_source(entry)) .with_context(|| format!("Region {:?} from previous step must exist", coords))?; let max_timestamp = *sources From 2a92eefd09f3e75787d68a7cd95dea2e3f707a9d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 18 Aug 2023 18:34:12 +0200 Subject: [PATCH 231/460] resource/generate.py: fix usage message --- resource/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/generate.py b/resource/generate.py index fabff63..73bb91d 100755 --- a/resource/generate.py +++ b/resource/generate.py @@ -6,7 +6,7 @@ import sys if len(sys.argv) != 3: - sys.exit('Usage: extract.py ') + sys.exit('Usage: generate.py ') with open(sys.argv[1]) as f: colors = json.load(f) From 0542f2ea1199f326df05de8655910bcdf3f68343 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 18 Aug 2023 18:34:22 +0200 Subject: [PATCH 232/460] resource/README.md: update for Rust implementation --- resource/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resource/README.md b/resource/README.md index f9dc955..5211fd3 100644 --- a/resource/README.md +++ b/resource/README.md @@ -10,7 +10,7 @@ work. of two different versions - `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 `BlockType.inc.cpp` from `colors.json` +- `generate.py`: Generates `block_types.rs` from `colors.json` In addition to these scripts, the JSON processor *jq* is a useful tool to work with MinedMap's resource metadata. @@ -63,7 +63,8 @@ with MinedMap's resource metadata. 7. Update the source code with the new block colors: ```sh - ./generate.py colors.json ../src/Resource/BlockType.inc.cpp + ./generate.py colors.json ../src/resource/block_types.rs + cargo fmt ``` After the update, the new version should be tested with old savegames (both From 0842cb4ec2c193f0ba5a00018221ca3881d4607b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 18 Aug 2023 19:20:21 +0200 Subject: [PATCH 233/460] Rename library crate to minedmap-core Rustdoc can't deal with a bin and lib crate with the same name. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/bin/minedmap/common.rs | 2 +- src/bin/minedmap/main.rs | 2 ++ src/bin/minedmap/metadata_writer.rs | 9 +++++---- src/bin/minedmap/region_processor.rs | 20 +++++++++++--------- src/bin/minedmap/tile_mipmapper.rs | 7 ++++--- src/bin/minedmap/tile_renderer.rs | 16 +++++++++------- src/bin/nbtdump.rs | 2 +- src/bin/regiondump.rs | 2 +- 10 files changed, 36 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcf88f7..e6735e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,7 +552,7 @@ dependencies = [ ] [[package]] -name = "minedmap" +name = "minedmap-core" version = "0.1.0" dependencies = [ "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 111ee92..62fcd3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "minedmap" +name = "minedmap-core" version = "0.1.0" edition = "2021" license = "MIT" diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index 48cebf8..df15d99 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -7,7 +7,7 @@ use std::{ use indexmap::IndexSet; use serde::{Deserialize, Serialize}; -use minedmap::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; +use super::core::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; // Increase to force regeneration of all output files pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index ebeae87..046fbb5 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -5,6 +5,8 @@ mod region_processor; mod tile_mipmapper; mod tile_renderer; +use minedmap_core as core; + use std::path::PathBuf; use anyhow::{Context, Result}; diff --git a/src/bin/minedmap/metadata_writer.rs b/src/bin/minedmap/metadata_writer.rs index 3862362..98b086a 100644 --- a/src/bin/minedmap/metadata_writer.rs +++ b/src/bin/minedmap/metadata_writer.rs @@ -1,8 +1,10 @@ use anyhow::{Context, Result}; -use minedmap::{io::fs, world::de}; use serde::Serialize; -use super::common::*; +use super::{ + common::*, + core::{self, io::fs, world::de}, +}; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] @@ -77,8 +79,7 @@ impl<'a> MetadataWriter<'a> { } fn read_level_dat(&self) -> Result { - minedmap::io::data::from_file(&self.config.level_dat_path) - .context("Failed to read level.dat") + core::io::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") } fn spawn(level_dat: &de::LevelDat) -> Spawn { diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 6aa2cb4..983aa03 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -4,18 +4,20 @@ use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use minedmap::{ - io::{fs, storage}, - resource::{self, Biome}, - types::*, - world::{ +use super::{ + common::*, + core::{ self, - layer::{self, LayerData}, + io::{fs, storage}, + resource::{self, Biome}, + types::*, + world::{ + self, + layer::{self, LayerData}, + }, }, }; -use super::common::*; - /// Parses a filename in the format r.X.Z.mca into the contained X and Z values fn parse_region_filename(file_name: &OsStr) -> Option { let parts: Vec<_> = file_name.to_str()?.split('.').collect(); @@ -136,7 +138,7 @@ impl<'a> RegionProcessor<'a> { println!("Processing region r.{}.{}.mca", coords.x, coords.z); - minedmap::io::region::from_file(path)?.foreach_chunk( + core::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData { blocks, diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 4a8cf63..14a2ec0 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -1,9 +1,10 @@ use anyhow::{Context, Result}; use rayon::prelude::*; -use minedmap::{io::fs, types::*}; - -use super::common::*; +use super::{ + common::*, + core::{io::fs, types::*}, +}; pub struct TileMipmapper<'a> { config: &'a Config, diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index bc59b23..409db6d 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -11,15 +11,17 @@ use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; -use minedmap::{ - io::{fs, storage}, - resource::{block_color, needs_biome}, - types::*, - util::coord_offset, +use super::{ + common::*, + core::{ + io::{fs, storage}, + resource::{block_color, needs_biome}, + types::*, + util::coord_offset, + }, + region_group::RegionGroup, }; -use super::{common::*, region_group::RegionGroup}; - type RegionRef = Arc; fn biome_at( diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index d944cf2..e68c376 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -12,7 +12,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let value: fastnbt::Value = minedmap::io::data::from_file(args.file.as_path())?; + let value: fastnbt::Value = minedmap_core::io::data::from_file(args.file.as_path())?; println!("{:#x?}", value); Ok(()) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index f3b7210..9dfac2f 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -12,7 +12,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - minedmap::io::region::from_file(args.file.as_path())?.foreach_chunk( + minedmap_core::io::region::from_file(args.file.as_path())?.foreach_chunk( |coords, value: fastnbt::Value| { println!("Chunk {:?}: {:#x?}", coords, value); Ok(()) From ba86dc8c062b9811c994fbc03955799bbbd0851d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 19 Aug 2023 16:01:51 +0200 Subject: [PATCH 234/460] resource: use serde feature of enumflags2 crate --- Cargo.lock | 1 + Cargo.toml | 2 +- src/resource/mod.rs | 23 ++--------------------- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6735e0..06f1283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,6 +292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" dependencies = [ "enumflags2_derive", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 62fcd3c..664b976 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ anyhow = "1.0.68" bincode = "1.3.3" bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } -enumflags2 = "0.7.5" +enumflags2 = { version = "0.7.5", features = ["serde"] } fastnbt = "2.3.2" flate2 = "1.0.25" futures-util = "0.3.28" diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 5eb2838..501156a 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -6,12 +6,11 @@ mod legacy_block_types; use std::collections::HashMap; use enumflags2::{bitflags, BitFlags}; - -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; #[bitflags] #[repr(u8)] -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] pub enum BlockFlag { Opaque, Grass, @@ -21,29 +20,11 @@ pub enum BlockFlag { Water, } -fn serialize_block_flags(flags: &BitFlags, serializer: S) -> Result -where - S: Serializer, -{ - flags.bits().serialize(serializer) -} -fn deserialize_block_flags<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let bits = u8::deserialize(deserializer)?; - BitFlags::::from_bits(bits).map_err(de::Error::custom) -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Color(pub [u8; 3]); #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockType { - #[serde( - serialize_with = "serialize_block_flags", - deserialize_with = "deserialize_block_flags" - )] pub flags: BitFlags, pub color: Color, } From 05a8056cbf17ed3efcdc0f558901891b560809c8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 18 Aug 2023 19:13:43 +0200 Subject: [PATCH 235/460] Add documentation comments for all items --- src/bin/minedmap/common.rs | 68 +++++++++++++++++++++----- src/bin/minedmap/main.rs | 7 +++ src/bin/minedmap/metadata_writer.rs | 24 ++++++++++ src/bin/minedmap/region_group.rs | 29 ++++++++++- src/bin/minedmap/region_processor.rs | 19 ++++++++ src/bin/minedmap/tile_mipmapper.rs | 17 +++++++ src/bin/minedmap/tile_renderer.rs | 39 +++++++++++++++ src/bin/nbtdump.rs | 6 +++ src/bin/regiondump.rs | 6 +++ src/io/data.rs | 4 ++ src/io/fs.rs | 38 +++++++++++++++ src/io/mod.rs | 2 + src/io/region.rs | 20 ++++++++ src/io/storage.rs | 8 ++++ src/lib.rs | 5 ++ src/resource/biomes.rs | 50 +++++++++++++++++-- src/resource/block_color.rs | 26 ++++++++++ src/resource/legacy_block_types.rs | 6 +++ src/resource/mod.rs | 28 ++++++++++- src/types.rs | 35 ++++++++++++-- src/util.rs | 7 +++ src/world/chunk.rs | 24 ++++++++++ src/world/de.rs | 34 ++++++++++++- src/world/layer.rs | 42 +++++++++++++++- src/world/mod.rs | 2 + src/world/section.rs | 72 +++++++++++++++++++++------- 26 files changed, 576 insertions(+), 42 deletions(-) diff --git a/src/bin/minedmap/common.rs b/src/bin/minedmap/common.rs index df15d99..4183b64 100644 --- a/src/bin/minedmap/common.rs +++ b/src/bin/minedmap/common.rs @@ -1,3 +1,5 @@ +//! Common data types and functions used by multiple generation steps + use std::{ collections::{BTreeMap, BTreeSet}, fmt::Debug, @@ -9,12 +11,19 @@ use serde::{Deserialize, Serialize}; use super::core::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; -// Increase to force regeneration of all output files +/// MinedMap data version number +/// +/// Increase to force regeneration of all output files pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); +/// Coordinate pair of a generated tile +/// +/// Each tile corresponds to one Minecraft region file #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TileCoords { + /// The X coordinate pub x: i32, + /// The Z coordinate pub z: i32, } @@ -24,11 +33,16 @@ impl Debug for TileCoords { } } +/// Set of tile coordinates +/// +/// Used to store list of populated tiles for each mipmap level in the +/// viewer metadata file. #[derive(Debug, Clone, Default, Serialize)] #[serde(transparent)] pub struct TileCoordMap(pub BTreeMap>); impl TileCoordMap { + /// Checks whether the map contains a given coordinate pair pub fn contains(&self, coords: TileCoords) -> bool { let Some(xs) = self.0.get(&coords.z) else { return false; @@ -38,39 +52,62 @@ impl TileCoordMap { } } +/// Data structure for storing chunk data between processing and rendering steps #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProcessedChunk { + /// Block type data pub blocks: Box, + /// Biome data pub biomes: Box, + /// Block height/depth data pub depths: Box, } +/// Data structure for storing region data between processing and rendering steps #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ProcessedRegion { + /// List of biomes used in the region + /// + /// Indexed by [ProcessedChunk] biome data pub biome_list: IndexSet, + /// Processed chunk data pub chunks: ChunkArray>>, } -pub struct Config { - pub num_threads: usize, - pub region_dir: PathBuf, - pub processed_dir: PathBuf, - pub output_dir: PathBuf, - pub level_dat_path: PathBuf, - pub metadata_path: PathBuf, -} - +/// Derives a filename from region coordinates and a file extension +/// +/// Can be used for input regions, processed data or rendered tiles fn coord_filename(coords: TileCoords, ext: &str) -> String { format!("r.{}.{}.{}", coords.x, coords.z, ext) } +/// Tile kind corresponding to a map layer #[derive(Debug, Clone, Copy)] pub enum TileKind { + /// Regular map tile contains block colors Map, + /// Lightmap tile for illumination layer Lightmap, } +/// Common configuration based on command line arguments +pub struct Config { + /// Number of threads for parallel processing + pub num_threads: usize, + /// Path of input region directory + pub region_dir: PathBuf, + /// Path of input `level.dat` file + pub level_dat_path: PathBuf, + /// Base path for storage of rendered tile data + pub output_dir: PathBuf, + /// Path for storage of intermediate processed data files + pub processed_dir: PathBuf, + /// Path of viewer metadata file + pub metadata_path: PathBuf, +} + impl Config { + /// Crates a new [Config] from [command line arguments](super::Args) pub fn new(args: &super::Args) -> Self { let num_threads = match args.jobs { Some(0) => num_cpus::get(), @@ -79,30 +116,33 @@ impl Config { }; let region_dir = [&args.input_dir, Path::new("region")].iter().collect(); - let processed_dir = [&args.output_dir, Path::new("processed")].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 metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect(); Config { num_threads, region_dir, - processed_dir, - output_dir: args.output_dir.clone(), level_dat_path, + output_dir: args.output_dir.clone(), + processed_dir, metadata_path, } } + /// Constructs the path to an input region file pub fn region_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "mca"); [&self.region_dir, Path::new(&filename)].iter().collect() } + /// Constructs the path of an intermediate processed region file pub fn processed_path(&self, coords: TileCoords) -> PathBuf { let filename = coord_filename(coords, "bin"); [&self.processed_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 { TileKind::Map => "map", @@ -112,6 +152,7 @@ impl Config { [&self.output_dir, Path::new(&dir)].iter().collect() } + /// 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 dir = self.tile_dir(kind, level); @@ -119,6 +160,7 @@ impl Config { } } +/// Copies a chunk image into a region tile pub fn overlay_chunk(image: &mut I, chunk: &J, coords: ChunkCoords) where I: image::GenericImage, diff --git a/src/bin/minedmap/main.rs b/src/bin/minedmap/main.rs index 046fbb5..925a38b 100644 --- a/src/bin/minedmap/main.rs +++ b/src/bin/minedmap/main.rs @@ -1,3 +1,8 @@ +//! The minedmap generator renders map tile images from Minecraft save data + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + mod common; mod metadata_writer; mod region_group; @@ -18,6 +23,7 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; +/// Command line arguments for minedmap #[derive(Debug, Parser)] pub struct Args { /// Number of parallel threads to use for processing @@ -32,6 +38,7 @@ pub struct Args { pub output_dir: PathBuf, } +/// Configures the Rayon thread pool for parallel processing fn setup_threads(num_threads: usize) -> Result<()> { rayon::ThreadPoolBuilder::new() .num_threads(num_threads) diff --git a/src/bin/minedmap/metadata_writer.rs b/src/bin/minedmap/metadata_writer.rs index 98b086a..2ba6038 100644 --- a/src/bin/minedmap/metadata_writer.rs +++ b/src/bin/minedmap/metadata_writer.rs @@ -1,3 +1,5 @@ +//! The [MetadataWriter] and related types + use anyhow::{Context, Result}; use serde::Serialize; @@ -6,43 +8,62 @@ use super::{ core::{self, io::fs, world::de}, }; +/// Minimum and maximum X and Z tile coordinates for a mipmap level #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct Bounds { + /// Minimum X coordinate min_x: i32, + /// Maximum X coordinate max_x: i32, + /// Minimum Z coordinate min_z: i32, + /// Maximum Z coordinate max_z: i32, } +/// Mipmap level information in viewer metadata file #[derive(Debug, Serialize)] struct Mipmap<'t> { + /// Minimum and maximum tile coordinates of the mipmap level bounds: Bounds, + /// Map of populated tiles for the mipmap level regions: &'t TileCoordMap, } +/// Initial spawn point for new players #[derive(Debug, Serialize)] struct Spawn { + /// Spawn X coordinate x: i32, + /// Spawn Z coordinate z: i32, } +/// Viewer metadata JSON data structure #[derive(Debug, Serialize)] struct Metadata<'t> { + /// Tile information for each mipmap level mipmaps: Vec>, + /// Initial spawn point for new players spawn: Spawn, } +/// The MetadataWriter is used to generate the viewer metadata file pub struct MetadataWriter<'a> { + /// Common MinedMap configuration from command line config: &'a Config, + /// Map of generated tiles for each mipmap level tiles: &'a [TileCoordMap], } impl<'a> MetadataWriter<'a> { + /// Creates a new MetadataWriter pub fn new(config: &'a Config, tiles: &'a [TileCoordMap]) -> Self { MetadataWriter { config, tiles } } + /// Helper to construct a [Mipmap] data structure from a [TileCoordMap] fn mipmap_entry(regions: &TileCoordMap) -> Mipmap { let mut min_x = i32::MAX; let mut max_x = i32::MIN; @@ -78,10 +99,12 @@ impl<'a> MetadataWriter<'a> { } } + /// Reads and deserializes the `level.dat` of the Minecraft save data fn read_level_dat(&self) -> Result { core::io::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") } + /// Generates [Spawn] data from a [de::LevelDat] fn spawn(level_dat: &de::LevelDat) -> Spawn { Spawn { x: level_dat.data.spawn_x, @@ -89,6 +112,7 @@ impl<'a> MetadataWriter<'a> { } } + /// Runs the viewer metadata file generation pub fn run(self) -> Result<()> { let level_dat = self.read_level_dat()?; diff --git a/src/bin/minedmap/region_group.rs b/src/bin/minedmap/region_group.rs index be46511..4357a8f 100644 --- a/src/bin/minedmap/region_group.rs +++ b/src/bin/minedmap/region_group.rs @@ -1,3 +1,5 @@ +//! The generic [RegionGroup] data structure + use std::{future::Future, iter}; use anyhow::Result; @@ -5,17 +7,27 @@ use futures_util::future::OptionFuture; /// A generic array of 3x3 elements /// -/// A RegionGroup is used to store information about a 3x3 neighbourhood of +/// A RegionGroup is used to store information about a 3x3 neighborhood of /// regions. /// /// The center element is always populated, while the 8 adjacent elements may be None. #[derive(Debug, Clone, Copy)] pub struct RegionGroup { + /// The element corresponding to the center of the 9x9 neighborhood center: T, + /// The remaining elements, stored in row-first order + /// + /// The center element is always None. neighs: [Option; 9], } impl RegionGroup { + /// Constructs a new RegionGroup from a closure called for each element + /// + /// The X and Z coordinates relative to the center (in the range -1..1) + /// are passed to the closure. + /// + /// Panics of the closure returns None for the center element. pub fn new(f: F) -> Self where F: Fn(i8, i8) -> Option, @@ -36,10 +48,14 @@ impl RegionGroup { } } + /// Returns a reference to the center element pub fn center(&self) -> &T { &self.center } + /// Returns a reference to an element of the RegionGroup, if populated + /// + /// Always returns None for X and Z coordinates outside of the -1..1 range. pub fn get(&self, x: i8, z: i8) -> Option<&T> { if (x, z) == (0, 0) { return Some(&self.center); @@ -50,6 +66,7 @@ impl RegionGroup { self.neighs.get((3 * x + z + 4) as usize)?.as_ref() } + /// Runs a closure on each element to construct a new RegionGroup pub fn map(self, mut f: F) -> RegionGroup where F: FnMut(T) -> U, @@ -60,6 +77,10 @@ impl RegionGroup { } } + /// Runs a fallible closure on each element to construct a new RegionGroup + /// + /// [Err] return values for the center element are passed up. Outer elements + /// become unpopulated when the closure fails. pub fn try_map(self, mut f: F) -> Result> where F: FnMut(T) -> Result, @@ -70,6 +91,7 @@ impl RegionGroup { Ok(RegionGroup { center, neighs }) } + /// Runs an asynchronous closure on each element to construct a new RegionGroup #[allow(dead_code)] pub async fn async_map(self, mut f: F) -> RegionGroup where @@ -88,6 +110,10 @@ impl RegionGroup { } } + /// Runs a fallible asynchronous closure on each element to construct a new RegionGroup + /// + /// [Err] return values for the center element are passed up. Outer elements + /// become unpopulated when the closure fails. pub async fn async_try_map(self, mut f: F) -> Result> where Fut: Future>, @@ -110,6 +136,7 @@ impl RegionGroup { Ok(RegionGroup { center, neighs }) } + /// Returns an [Iterator] over all populated elements pub fn iter(&self) -> impl Iterator { iter::once(&self.center).chain(self.neighs.iter().filter_map(Option::as_ref)) } diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index 983aa03..7168ebd 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -1,3 +1,5 @@ +//! The [RegionProcessor] and related functions + use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; @@ -32,13 +34,20 @@ fn parse_region_filename(file_name: &OsStr) -> Option { } /// Type with methods for processing the regions of a Minecraft save directory +/// +/// The RegionProcessor builds lightmap tiles as well as processed region data +/// consumed by subsequent generation steps. pub struct RegionProcessor<'a> { + /// Registry of known block types block_types: resource::BlockTypes, + /// Registry of known biome types biome_types: resource::BiomeTypes, + /// Common MinedMap configuration from command line config: &'a Config, } impl<'a> RegionProcessor<'a> { + /// Constructs a new RegionProcessor pub fn new(config: &'a Config) -> Self { RegionProcessor { block_types: resource::BlockTypes::default(), @@ -47,6 +56,7 @@ impl<'a> RegionProcessor<'a> { } } + /// Generates a list of all regions of the input Minecraft save data fn collect_regions(&self) -> Result> { Ok(self .config @@ -80,9 +90,11 @@ impl<'a> RegionProcessor<'a> { world::layer::top_layer(biome_list, &chunk) } + /// Renders a lightmap subtile from chunk block light data fn render_chunk_lightmap( block_light: Box, ) -> image::GrayAlphaImage { + /// Width/height of generated chunk lightmap const N: u32 = BLOCKS_PER_CHUNK as u32; image::GrayAlphaImage::from_fn(N, N, |x, z| { @@ -95,6 +107,9 @@ impl<'a> RegionProcessor<'a> { }) } + /// Saves processed region data + /// + /// The timestamp is the time of the last modification of the input region data. fn save_region( path: &Path, processed_region: &ProcessedRegion, @@ -103,6 +118,9 @@ impl<'a> RegionProcessor<'a> { storage::write(path, processed_region, FILE_META_VERSION, timestamp) } + /// Saves a lightmap tile + /// + /// The timestamp is the time of the last modification of the input region data. fn save_lightmap( path: &Path, lightmap: &image::GrayAlphaImage, @@ -117,6 +135,7 @@ impl<'a> RegionProcessor<'a> { /// Processes a single region file fn process_region(&self, coords: TileCoords) -> Result<()> { + /// Width/height of the region data const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let mut processed_region = ProcessedRegion::default(); diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 14a2ec0..59c2880 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -1,3 +1,5 @@ +//! The [TileMipmapper] + use anyhow::{Context, Result}; use rayon::prelude::*; @@ -6,16 +8,24 @@ use super::{ core::{io::fs, types::*}, }; +/// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'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> 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 @@ -23,6 +33,7 @@ impl<'a> TileMipmapper<'a> { .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(); @@ -38,6 +49,10 @@ impl<'a> TileMipmapper<'a> { ret } + /// Renders and saves a single mipmap tile image + /// + /// Each mipmap tile is rendered by taking 2x2 tiles from the + /// previous level and scaling them down by 50%. fn render_mipmap( &self, kind: TileKind, @@ -49,6 +64,7 @@ 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); @@ -131,6 +147,7 @@ impl<'a> TileMipmapper<'a> { }) } + /// Runs the mipmap generation pub fn run(self) -> Result> { let mut tile_stack = { let mut tile_map = TileCoordMap::default(); diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 409db6d..d5b7644 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -1,3 +1,5 @@ +//! The [TileRenderer] and related types and functions + use std::{ num::NonZeroUsize, path::PathBuf, @@ -22,8 +24,16 @@ use super::{ region_group::RegionGroup, }; +/// Type for referencing loaded [ProcessedRegion] data type RegionRef = Arc; +/// Returns the index of the biome at a block coordinate +/// +/// The passed chunk and block coordinates relative to the center of the +/// region group is offset by *dx* and *dz*. +/// +/// The returned tuple contains the relative region coordinates the offset coordinate +/// ends up in (in the range -1..1) and the index in that region's biome list. fn biome_at( region_group: &RegionGroup, chunk: ChunkCoords, @@ -49,15 +59,22 @@ fn biome_at( )) } +/// The TileRenderer generates map tiles from processed region data pub struct TileRenderer<'a> { + /// Common MinedMap configuration from command line config: &'a Config, + /// Runtime for asynchronous region loading rt: &'a tokio::runtime::Runtime, + /// List of populated regions to render tiles for regions: &'a [TileCoords], + /// Set of populated regions for fast existence checking region_set: rustc_hash::FxHashSet, + /// Cache of previously loaded regions region_cache: Mutex>>>, } impl<'a> TileRenderer<'a> { + /// Constructs a new TileRenderer pub fn new( config: &'a Config, rt: &'a tokio::runtime::Runtime, @@ -76,6 +93,7 @@ impl<'a> TileRenderer<'a> { } } + /// Loads [ProcessedRegion] for a region or returns previously loaded data from the region cache async fn load_region(&self, processed_path: PathBuf) -> Result { let region_loader = { let mut region_cache = self.region_cache.lock().unwrap(); @@ -96,6 +114,7 @@ impl<'a> TileRenderer<'a> { .cloned() } + /// Loads a 3x3 neighborhood of processed region data async fn load_region_group( &self, processed_paths: RegionGroup, @@ -105,18 +124,29 @@ impl<'a> TileRenderer<'a> { .await } + /// Computes the color of a tile pixel fn block_color_at( region_group: &RegionGroup, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, ) -> Option { + /// Helper for keys in the weight table + /// + /// 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 } + /// One quadrant of the kernel used to smooth biome edges + /// + /// The kernel is mirrored in X und Z direction to build the full 5x5 + /// smoothing kernel. const SMOOTH: [[f32; 3]; 3] = [[41.0, 26.0, 7.0], [26.0, 16.0, 4.0], [7.0, 4.0, 1.0]]; + /// Maximum X coordinate offset to take into account for biome smoothing const X: isize = SMOOTH[0].len() as isize - 1; + /// Maximum Z coordinate offset to take into account for biome smoothing const Z: isize = SMOOTH.len() as isize - 1; let block = chunk.blocks[block_coords]?; @@ -168,12 +198,14 @@ impl<'a> TileRenderer<'a> { Some(color / total) } + /// Renders a chunk subtile into a region tile image fn render_chunk( image: &mut image::RgbaImage, region_group: &RegionGroup, chunk: &ProcessedChunk, chunk_coords: ChunkCoords, ) { + /// Width/height of a chunk subtile const N: u32 = BLOCKS_PER_CHUNK as u32; let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| { @@ -191,6 +223,7 @@ impl<'a> TileRenderer<'a> { overlay_chunk(image, &chunk_image, chunk_coords); } + /// Renders a region tile image fn render_region(image: &mut image::RgbaImage, region_group: &RegionGroup) { for (coords, chunk) in region_group.center().chunks.iter() { let Some(chunk) = chunk else { @@ -201,12 +234,15 @@ impl<'a> TileRenderer<'a> { } } + /// Returns the filename of the processed data for a region and the time of its last modification fn processed_source(&self, coords: TileCoords) -> Result<(PathBuf, SystemTime)> { let path = self.config.processed_path(coords); let timestamp = fs::modified_timestamp(&path)?; Ok((path, timestamp)) } + /// Returns the filenames of the processed data for a 3x3 neighborhood of a region + /// and the time of last modification for any of them fn processed_sources(&self, coords: TileCoords) -> Result<(RegionGroup, SystemTime)> { let sources = RegionGroup::new(|x, z| { Some(TileCoords { @@ -228,7 +264,9 @@ impl<'a> TileRenderer<'a> { Ok((paths, max_timestamp)) } + /// Renders and saves a region tile image fn render_tile(&self, coords: TileCoords) -> Result<()> { + /// Width/height of a tile image const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let (processed_paths, processed_timestamp) = self.processed_sources(coords)?; @@ -274,6 +312,7 @@ impl<'a> TileRenderer<'a> { ) } + /// Runs the tile generation pub fn run(self) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index e68c376..da5e502 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -1,8 +1,14 @@ +//! Dumps data from a NBT data file in a human-readable format + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + use std::path::PathBuf; use anyhow::Result; use clap::Parser; +/// Command line arguments for nbtdump #[derive(Debug, Parser)] struct Args { /// Filename to dump diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 9dfac2f..21351f7 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -1,8 +1,14 @@ +//! Dumps data from a region data file in a human-readable format + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + use std::path::PathBuf; use anyhow::Result; use clap::Parser; +/// Command line arguments for regiondump #[derive(Debug, Parser)] struct Args { /// Filename to dump diff --git a/src/io/data.rs b/src/io/data.rs index d475465..bb2ac3b 100644 --- a/src/io/data.rs +++ b/src/io/data.rs @@ -1,9 +1,12 @@ +//! Functions for reading and deserializing compressed NBT data + use std::{fs::File, io::prelude::*, path::Path}; use anyhow::{Context, Result}; use flate2::read::GzDecoder; use serde::de::DeserializeOwned; +/// Reads compressed NBT data from a reader and deserializes to a given data structure pub fn from_reader(reader: R) -> Result where R: Read, @@ -18,6 +21,7 @@ where fastnbt::from_bytes(&buf).context("Failed to decode NBT data") } +/// Reads compressed NBT data from a file and deserializes to a given data structure pub fn from_file(path: P) -> Result where P: AsRef, diff --git a/src/io/fs.rs b/src/io/fs.rs index 8f6a79a..7960b25 100644 --- a/src/io/fs.rs +++ b/src/io/fs.rs @@ -1,3 +1,5 @@ +//! Helpers and common functions for filesystem access + use std::{ fs::{self, File}, io::{BufReader, BufWriter, Read, Write}, @@ -8,15 +10,25 @@ use std::{ use anyhow::{Context, Ok, Result}; use serde::{Deserialize, Serialize}; +/// A file metadata version number +/// +/// Deserialized metadata with non-current version number are considered invalid #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub struct FileMetaVersion(pub u32); +/// Metadata stored with generated files to track required incremental updates #[derive(Debug, Serialize, Deserialize)] struct FileMeta { + /// Version of data described by the FileMeta version: FileMetaVersion, + /// Timestamp stored with generated data + /// + /// This timestamp is always the time of last modification of the inputs + /// that were used to generate the file described by the FileMeta. timestamp: SystemTime, } +/// Helper for creating suffixed file paths fn suffix_name(path: &Path, suffix: &str) -> PathBuf { let mut file_name = path.file_name().unwrap_or_default().to_os_string(); file_name.push(suffix); @@ -26,24 +38,35 @@ fn suffix_name(path: &Path, suffix: &str) -> PathBuf { ret } +/// Derives the filename for temporary storage of data during generation fn tmpfile_name(path: &Path) -> PathBuf { suffix_name(path, ".tmp") } +/// Derives the filename for associated metadata for generated files fn metafile_name(path: &Path) -> PathBuf { suffix_name(path, ".meta") } +/// Creates a directory including all its parents +/// +/// Wrapper around [fs::create_dir_all] that adds a more descriptive error message pub fn create_dir_all(path: &Path) -> Result<()> { fs::create_dir_all(path) .with_context(|| format!("Failed to create directory {}", path.display(),)) } +/// Renames a file or directory +/// +/// Wrapper around [fs::rename] that adds a more descriptive error message pub fn rename(from: &Path, to: &Path) -> Result<()> { fs::rename(from, to) .with_context(|| format!("Failed to rename {} to {}", from.display(), to.display())) } +/// Creates a new file +/// +/// The contents of the file are defined by the passed function. pub fn create(path: &Path, f: F) -> Result where F: FnOnce(&mut BufWriter) -> Result, @@ -60,6 +83,7 @@ where .with_context(|| format!("Failed to write file {}", path.display())) } +/// Checks whether the contents of two files are equal pub fn equal(path1: &Path, path2: &Path) -> Result { let mut file1 = BufReader::new( fs::File::open(path1) @@ -81,6 +105,12 @@ pub fn equal(path1: &Path, path2: &Path) -> Result { }) } +/// Creates a new file, temporarily storing its contents in a temporary file +/// +/// Storing the data in a temporary file prevents leaving half-written files +/// when the function is interrupted. In addition, the old and new contents of +/// the file are compared if a file with the same name already exists, and the +/// file timestamp is only updated if the contents have changed. pub fn create_with_tmpfile(path: &Path, f: F) -> Result where F: FnOnce(&mut BufWriter) -> Result, @@ -104,6 +134,7 @@ where ret } +/// Returns the time of last modification for a given file path pub fn modified_timestamp(path: &Path) -> Result { fs::metadata(path) .and_then(|meta| meta.modified()) @@ -115,6 +146,8 @@ pub fn modified_timestamp(path: &Path) -> Result { }) } +/// Reads the stored timestamp from file metadata for a file previously written +/// using [create_with_timestamp] pub fn read_timestamp(path: &Path, version: FileMetaVersion) -> Option { let meta_path = metafile_name(path); let mut file = BufReader::new(fs::File::open(meta_path).ok()?); @@ -127,6 +160,11 @@ pub fn read_timestamp(path: &Path, version: FileMetaVersion) -> Option( path: &Path, version: FileMetaVersion, diff --git a/src/io/mod.rs b/src/io/mod.rs index 681d75d..590ca2a 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,3 +1,5 @@ +//! Input/output functions + pub mod data; pub mod fs; pub mod region; diff --git a/src/io/region.rs b/src/io/region.rs index e5c2528..82f5604 100644 --- a/src/io/region.rs +++ b/src/io/region.rs @@ -1,3 +1,5 @@ +//! Functions for reading and deserializing region data + use std::{ fs::File, io::{prelude::*, SeekFrom}, @@ -10,15 +12,24 @@ use serde::de::DeserializeOwned; use crate::types::*; +/// Data block size of region data files +/// +/// After one header block, the region file consists of one or more consecutive blocks +/// of data for each populated chunk. const BLOCKSIZE: usize = 4096; +/// Chunk descriptor extracted from region file header #[derive(Debug)] struct ChunkDesc { + /// Offset of data block where the chunk starts offset: u32, + /// Number of data block used by the chunk len: u8, + /// Coodinates of chunk described by this descriptor coords: ChunkCoords, } +/// Parses the header of a region data file fn parse_header(header: &ChunkArray) -> Vec { let mut chunks: Vec<_> = header .iter() @@ -45,6 +56,7 @@ fn parse_header(header: &ChunkArray) -> Vec { chunks } +/// Decompresses chunk data and deserializes to a given data structure fn decode_chunk(buf: &[u8]) -> Result where T: DeserializeOwned, @@ -63,12 +75,18 @@ where fastnbt::from_bytes(&decode_buffer).context("Failed to decode NBT data") } +/// Wraps a reader used to read a region data file #[derive(Debug)] pub struct Region { + /// The wrapper reader reader: R, } impl Region { + /// Iterates over the chunks of the region data + /// + /// The order of iteration is based on the order the chunks appear in the + /// data file. pub fn foreach_chunk(self, mut f: F) -> Result<()> where R: Read + Seek, @@ -126,6 +144,7 @@ impl Region { } } +/// Creates a new [Region] from a reader pub fn from_reader(reader: R) -> Region where R: Read + Seek, @@ -133,6 +152,7 @@ where Region { reader } } +/// Creates a new [Region] for a file pub fn from_file

(path: P) -> Result> where P: AsRef, diff --git a/src/io/storage.rs b/src/io/storage.rs index 4ba6050..99a8d63 100644 --- a/src/io/storage.rs +++ b/src/io/storage.rs @@ -1,3 +1,7 @@ +//! Functions for serializing and deserializing MinedMap data structures efficiently +//! +//! Data is serialized using Bincode and compressed using zstd. + use std::{ fs::File, io::{Read, Write}, @@ -10,6 +14,9 @@ use serde::{de::DeserializeOwned, Serialize}; use super::fs; +/// Serializes data and stores it in a file +/// +/// A timestamp is stored in an assiciated metadata file. pub fn write( path: &Path, value: &T, @@ -29,6 +36,7 @@ pub fn write( }) } +/// Reads data from a file and deserializes it pub fn read(path: &Path) -> Result { (|| -> Result { let mut file = File::open(path)?; diff --git a/src/lib.rs b/src/lib.rs index f46a9d2..14d97f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,8 @@ +//! Common library for MinedMap generator and dump utilities + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + pub mod io; pub mod resource; pub mod types; diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs index 0515e93..54859df 100644 --- a/src/resource/biomes.rs +++ b/src/resource/biomes.rs @@ -1,25 +1,51 @@ +//! Biome data structures + 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 } @@ -33,6 +59,7 @@ impl Biome { } } + /// Builder function to override the biome water color const fn water(self, water_color: [u8; 3]) -> Biome { Biome { water_color: Some(Color(water_color)), @@ -40,6 +67,7 @@ impl Biome { } } + /// Builder function to override the biome foliage color const fn foliage(self, foliage_color: [u8; 3]) -> Biome { Biome { foliage_color: Some(Color(foliage_color)), @@ -47,6 +75,7 @@ impl Biome { } } + /// Builder function to override the biome grass color const fn grass(self, grass_color: [u8; 3]) -> Biome { Biome { grass_color: Some(Color(grass_color)), @@ -54,6 +83,7 @@ impl Biome { } } + /// 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), @@ -61,25 +91,34 @@ impl Biome { } } + /// 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) } } -// Data extracted from Minecraft code decompiled using https://github.com/Hexeption/MCP-Reborn - -#[allow(clippy::zero_prefixed_literal)] +/// 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 ( @@ -189,6 +228,10 @@ pub const BIOMES: &[(&str, Biome)] = { ] }; +/// 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"), @@ -292,6 +335,7 @@ pub const BIOME_ALIASES: &[(&str, &str)] = &[ ("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", diff --git a/src/resource/block_color.rs b/src/resource/block_color.rs index b98aec9..3df9a54 100644 --- a/src/resource/block_color.rs +++ b/src/resource/block_color.rs @@ -1,15 +1,23 @@ +//! Functions for computations of block colors + use super::{Biome, BlockType, Color}; use glam::Vec3; +/// Converts an u8 RGB color to a float vector fn color_vec_unscaled(color: Color) -> Vec3 { Vec3::from_array(color.0.map(f32::from)) } +/// Converts an u8 RGB color to a float vector, scaling the components to 0.0..1.0 fn color_vec(color: Color) -> Vec3 { color_vec_unscaled(color) / 255.0 } +/// Helper for grass and foliage colors +/// +/// Biome temperature and downfall are modified based on the depth value +/// before using them to compute the final color fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { let temp = (biome.temp() - f32::max((depth - 64.0) / 600.0, 0.0)).clamp(0.0, 1.0); let downfall = biome.downfall().clamp(0.0, 1.0) * temp; @@ -17,9 +25,13 @@ fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { colors[0] + temp * colors[1] + downfall * colors[2] } +/// Extension trait with helpers for computing biome-specific block colors trait BiomeExt { + /// Returns the grass color of the biome at a given depth fn grass_color(&self, depth: f32) -> Vec3; + /// Returns the foliage color of the biome at a given depth fn foliage_color(&self, depth: f32) -> Vec3; + /// Returns the water color of the biome fn water_color(&self) -> Vec3; } @@ -27,12 +39,15 @@ impl BiomeExt for Biome { fn grass_color(&self, depth: f32) -> Vec3 { use super::BiomeGrassColorModifier::*; + /// Color matrix extracted from grass color texture const GRASS_COLORS: [Vec3; 3] = [ Vec3::new(0.502, 0.706, 0.592), // lower right Vec3::new(0.247, 0.012, -0.259), // lower left - lower right Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left ]; + /// Used for dark forst grass color modifier const DARK_FOREST_GRASS_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) + /// Grass color in swamp biomes const SWAMP_GRASS_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) let regular_color = || { @@ -49,6 +64,7 @@ impl BiomeExt for Biome { } fn foliage_color(&self, depth: f32) -> Vec3 { + /// Color matrix extracted from foliage color texture const FOLIAGE_COLORS: [Vec3; 3] = [ Vec3::new(0.376, 0.631, 0.482), // lower right Vec3::new(0.306, 0.012, -0.317), // lower left - lower right @@ -61,6 +77,9 @@ impl BiomeExt for Biome { } fn water_color(&self) -> Vec3 { + /// Default biome water color + /// + /// Used for biomes that don't explicitly set a water color const DEFAULT_WATER_COLOR: Vec3 = Vec3::new(0.247, 0.463, 0.894); // == color_vec(Color([63, 118, 228])) self.water_color @@ -69,15 +88,22 @@ impl BiomeExt for Biome { } } +/// Color multiplier for birch leaves const BIRCH_COLOR: Vec3 = Vec3::new(0.502, 0.655, 0.333); // == color_vec(Color([128, 167, 85])) +/// Color multiplier for spruce leaves const EVERGREEN_COLOR: Vec3 = Vec3::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 { use super::BlockFlag::*; block.is(Grass) || block.is(Foliage) || block.is(Water) } +/// Determined the block color to display for a given [BlockType] +/// +/// [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) -> Vec3 { use super::BlockFlag::*; diff --git a/src/resource/legacy_block_types.rs b/src/resource/legacy_block_types.rs index c5d9462..c027ac3 100644 --- a/src/resource/legacy_block_types.rs +++ b/src/resource/legacy_block_types.rs @@ -1,12 +1,18 @@ +//! Mapping of old numeric block type and damage/subtype IDs to new string IDs + +/// Helper for block types that don't use the damage/subtype data const fn simple(id: &str) -> [&str; 16] { [ id, id, id, id, id, id, id, id, id, id, id, id, id, id, id, id, ] } +/// Default block type for unassigned numeric IDs const DEF: &str = "air"; +/// Default entry for block type numbers that are unassigned regardless of subtype const EMPTY: [&str; 16] = simple(DEF); +/// Mapping from each numeric block type and damage/subtype ID to new string ID pub const LEGACY_BLOCK_TYPES: [[&str; 16]; 256] = [ /* 0 */ simple("air"), diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 501156a..459e783 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -1,43 +1,62 @@ +//! Data describing Minecraft biomes and block types + mod biomes; mod block_color; -mod block_types; mod legacy_block_types; +#[allow(clippy::missing_docs_in_private_items)] // Generated module +mod block_types; + use std::collections::HashMap; 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)] pub enum BlockFlag { + /// The block type is opaque Opaque, + /// The block type is colored using biome grass colors Grass, + /// The block type is colored using biome foliage colors Foliage, + /// The block type is birch foliage Birch, + /// The block type is spurce foliage Spruce, + /// The block type is colored using biome water colors Water, } +/// An RGB color #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct Color(pub [u8; 3]); +/// A block type specification #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct BlockType { + /// 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 pub fn is(&self, flag: BlockFlag) -> bool { self.flags.contains(flag) } } +/// Used to look up standard Minecraft block types #[derive(Debug)] pub struct BlockTypes { + /// Map of string IDs to block types block_type_map: HashMap, + /// Array used to look up old numeric block type and subtype values legacy_block_types: Box<[[BlockType; 16]; 256]>, } @@ -59,12 +78,14 @@ impl Default for BlockTypes { } impl BlockTypes { + /// Resolves a Minecraft 1.13+ string block type ID #[inline] pub fn get(&self, id: &str) -> Option { let suffix = id.strip_prefix("minecraft:")?; self.block_type_map.get(suffix).copied() } + /// 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]) @@ -74,9 +95,12 @@ impl BlockTypes { pub use biomes::{Biome, BiomeGrassColorModifier}; pub use block_color::{block_color, needs_biome}; +/// Used to look up standard Minecraft biome types #[derive(Debug)] pub struct BiomeTypes { + /// Map of string IDs to biome types biome_map: HashMap, + /// Array used to look up old numeric biome IDs legacy_biomes: Box<[&'static Biome; 256]>, } @@ -112,12 +136,14 @@ impl Default for BiomeTypes { } impl BiomeTypes { + /// Resolves a Minecraft 1.18+ string biome type ID #[inline] pub fn get(&self, id: &str) -> Option<&Biome> { let suffix = id.strip_prefix("minecraft:")?; self.biome_map.get(suffix).copied() } + /// Resolves a Minecraft pre-1.18 numeric biome type ID #[inline] pub fn get_legacy(&self, id: u8) -> Option<&Biome> { Some(self.legacy_biomes[id as usize]) diff --git a/src/types.rs b/src/types.rs index a28583d..045750b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,3 +1,5 @@ +//! Common types used by MinedMap + use std::{ fmt::Debug, iter::FusedIterator, @@ -7,14 +9,20 @@ use std::{ use itertools::iproduct; use serde::{Deserialize, Serialize}; +/// Const generic AXIS arguments for coordinate types pub mod axis { + /// The X axis pub const X: u8 = 0; + /// The Y axis (height) pub const Y: u8 = 1; + /// The Z axis pub const Z: u8 = 2; } +/// Generates a generic coordinate type with a given range macro_rules! coord_type { - ($t:ident, $max:expr) => { + ($t:ident, $max:expr, $doc:expr $(,)?) => { + #[doc = $doc] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct $t(pub u8); @@ -47,9 +55,15 @@ macro_rules! coord_type { }; } +/// Number of bits required to store a block coordinate pub const BLOCK_BITS: u8 = 4; +/// Number of blocks per chunk in each dimension pub const BLOCKS_PER_CHUNK: usize = 1 << BLOCK_BITS; -coord_type!(BlockCoord, BLOCKS_PER_CHUNK); +coord_type!( + BlockCoord, + BLOCKS_PER_CHUNK, + "A block coordinate relative to a chunk", +); /// A block X coordinate relative to a chunk pub type BlockX = BlockCoord<{ axis::X }>; @@ -63,7 +77,9 @@ pub type BlockZ = BlockCoord<{ axis::Z }>; /// X and Z coordinates of a block in a chunk #[derive(Clone, Copy, PartialEq, Eq)] pub struct LayerBlockCoords { + /// The X coordinate pub x: BlockX, + /// The Z coordinate pub z: BlockZ, } @@ -110,7 +126,9 @@ impl IndexMut for LayerBlockArray { /// X, Y and Z coordinates of a block in a chunk section #[derive(Clone, Copy, PartialEq, Eq)] pub struct SectionBlockCoords { + /// The X and Z coordinates pub xz: LayerBlockCoords, + /// The Y coordinate pub y: BlockY, } @@ -137,9 +155,15 @@ impl Debug for SectionBlockCoords { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct SectionY(pub i32); +/// Number of bits required to store a chunk coordinate pub const CHUNK_BITS: u8 = 5; +/// Number of chunks per region in each dimension pub const CHUNKS_PER_REGION: usize = 1 << CHUNK_BITS; -coord_type!(ChunkCoord, CHUNKS_PER_REGION); +coord_type!( + ChunkCoord, + CHUNKS_PER_REGION, + "A chunk coordinate relative to a region", +); /// A chunk X coordinate relative to a region pub type ChunkX = ChunkCoord<{ axis::X }>; @@ -150,7 +174,9 @@ pub type ChunkZ = ChunkCoord<{ axis::Z }>; /// A pair of chunk coordinates relative to a region #[derive(Clone, Copy, PartialEq, Eq)] pub struct ChunkCoords { + /// The X coordinate pub x: ChunkX, + /// The Z coordinate pub z: ChunkZ, } @@ -167,14 +193,17 @@ impl Debug for ChunkCoords { pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { + /// Iterates over all possible chunk coordinate pairs used as [ChunkArray] keys pub fn keys() -> impl Iterator + Clone + Debug { iproduct!(ChunkZ::iter(), ChunkX::iter()).map(|(z, x)| ChunkCoords { x, z }) } + /// Iterates over all values stored in the [ChunkArray] pub fn values(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| &self[k]) } + /// Iterates over pairs of chunk coordinate pairs and corresponding stored values pub fn iter(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| (k, &self[k])) } diff --git a/src/util.rs b/src/util.rs index b4fdefe..a128ef9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,10 @@ +//! Utility functions and extension traits + use crate::types::*; +/// Extension trait for combined bit shift and mask pub trait ShiftMask: Sized { + /// Output type of shift operation type MaskedOutput; /// Apply a right shift to a value, and return both the result and the @@ -27,6 +31,8 @@ impl ShiftMask for i32 { } } +/// Combines a coordinate split into region, chunk and block number to +/// a single linear coordinate #[inline] pub fn to_flat_coord( region: i8, @@ -36,6 +42,7 @@ pub fn to_flat_coord( (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 #[inline] pub fn from_flat_coord(coord: i32) -> (i8, ChunkCoord, BlockCoord) { let (region_chunk, block) = coord.shift_mask(BLOCK_BITS); diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 4f743fc..53ee165 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -1,3 +1,8 @@ +//! Higher-level interfaces to chunk data +//! +//! The data types in this module attempt to provide interfaces abstracting +//! over different data versions as much as possible. + use std::{ collections::{btree_map, BTreeMap}, iter::{self, FusedIterator}, @@ -17,6 +22,7 @@ use crate::{ pub enum Chunk<'a> { /// Minecraft v1.18+ chunk with biome data moved into sections V1_18 { + /// Section data section_map: BTreeMap, BiomesV1_18<'a>, BlockLight<'a>)>, }, /// Minecraft v1.13+ chunk @@ -26,14 +32,18 @@ pub enum Chunk<'a> { /// section), and a palette mapping these indices to namespaced /// block IDs V1_13 { + /// Section data section_map: BTreeMap, BlockLight<'a>)>, + /// Biome data biomes: BiomesV0<'a>, }, /// Original pre-1.13 chunk /// /// The original chunk format with fixed 8-bit numeric block IDs V0 { + /// Section data section_map: BTreeMap, BlockLight<'a>)>, + /// Biome data biomes: BiomesV0<'a>, }, /// Unpopulated chunk without any block data @@ -45,16 +55,21 @@ pub enum Chunk<'a> { 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]) @@ -64,6 +79,7 @@ enum SectionIterInner<'a> { /// Iterator over the sections of a [Chunk] #[derive(Debug, Clone)] pub struct SectionIter<'a> { + /// Inner iterator enum inner: SectionIterInner<'a>, } @@ -193,6 +209,7 @@ 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(), @@ -230,14 +247,20 @@ impl<'a> Chunk<'a> { } } +/// Reference to block, biome and block light data of a section #[derive(Debug, Clone, Copy)] pub struct SectionIterItem<'a> { + /// The Y coordinate of the section pub y: SectionY, + /// Section block data pub section: &'a dyn Section, + /// Section biome data pub biomes: &'a dyn Biomes, + /// Section block light data pub block_light: BlockLight<'a>, } +/// Helper trait to specify section iterator trait bounds trait SectionIterTrait<'a>: Iterator> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { @@ -252,6 +275,7 @@ impl<'a, T> SectionIterTrait<'a> for T where } impl<'a> SectionIter<'a> { + /// Helper to run a closure on the inner section iterator fn with_iter(&mut self, f: F) -> T where F: FnOnce(&mut dyn SectionIterTrait<'a>) -> T, diff --git a/src/world/de.rs b/src/world/de.rs index 82aa11c..cbedf31 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -6,30 +6,39 @@ use serde::Deserialize; #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct BlockStatePaletteEntry { + /// Block type ID pub name: String, } /// 1.18+ `block_states` element found in a [section](SectionV1_18) #[derive(Debug, Deserialize)] pub struct BlockStatesV1_18 { + /// Palette of block types, indexed by block data pub palette: Vec, + /// Block data pub data: Option, } /// 1.18+ `biomes` element found in a [section](SectionV1_18) #[derive(Debug, Deserialize)] pub struct BiomesV1_18 { + /// Palette of biome types, indexed by biome data pub palette: Vec, + /// Biome data pub data: Option, } /// Element of the 1.18+ `sections` list found in a [Chunk] #[derive(Debug, Deserialize)] pub struct SectionV1_18 { + /// Y coordinate #[serde(rename = "Y")] pub y: i32, + /// Block type data pub block_states: BlockStatesV1_18, + /// Biome data pub biomes: BiomesV1_18, + /// Block light data #[serde(rename = "BlockLight")] pub block_light: Option, } @@ -38,16 +47,23 @@ pub struct SectionV1_18 { #[derive(Debug, Deserialize)] #[serde(untagged)] pub enum SectionV0Variants { + /// v1.13+ data #[serde(rename_all = "PascalCase")] V1_13 { + /// Block data block_states: fastnbt::LongArray, + /// Block type palette, indexed by block data palette: Vec, }, + /// Pre-1.13 data #[serde(rename_all = "PascalCase")] V0 { + /// Block type data blocks: fastnbt::ByteArray, + /// Block damage / subtype data data: fastnbt::ByteArray, }, + /// Empty section Empty {}, } @@ -55,8 +71,11 @@ pub enum SectionV0Variants { #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct SectionV0 { + /// Y coordinate pub y: i8, + /// Block light data pub block_light: Option, + /// Version-specific data #[serde(flatten)] pub section: SectionV0Variants, } @@ -65,7 +84,9 @@ pub struct SectionV0 { #[derive(Debug, Deserialize)] #[serde(untagged)] pub enum BiomesV0 { + /// Data for Minecraft versions storing biome data as an IntArray IntArray(fastnbt::IntArray), + /// Data for Minecraft versions storing biome data as an ByteArray ByteArray(fastnbt::ByteArray), } @@ -73,8 +94,10 @@ pub enum BiomesV0 { #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LevelV0 { + /// Section data #[serde(default)] pub sections: Vec, + /// Biome data pub biomes: Option, } @@ -82,11 +105,15 @@ pub struct LevelV0 { #[derive(Debug, Deserialize)] #[serde(untagged)] pub enum ChunkVariants { + /// 1.18+ chunk data V1_18 { + /// List of chunk sections sections: Vec, }, + /// Pre-1.18 chunk data #[serde(rename_all = "PascalCase")] V0 { + /// `Level` field of the chunk level: LevelV0, }, } @@ -95,16 +122,20 @@ pub enum ChunkVariants { #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct Chunk { + /// The data version of the chunk pub data_version: Option, + /// Version-specific chunk data #[serde(flatten)] pub chunk: ChunkVariants, } -/// "Data" compound element of level.dat +/// `Data` compound element of level.dat #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LevelDatData { + /// X coordinate of spawn point for new players pub spawn_x: i32, + /// Z coordinate of spawn point for new players pub spawn_z: i32, } @@ -112,5 +143,6 @@ pub struct LevelDatData { #[derive(Debug, Deserialize)] #[serde(rename_all = "PascalCase")] pub struct LevelDat { + /// The `Data` field pub data: LevelDatData, } diff --git a/src/world/layer.rs b/src/world/layer.rs index 3abc30b..ce88107 100644 --- a/src/world/layer.rs +++ b/src/world/layer.rs @@ -1,3 +1,5 @@ +//! Functions to search the "top" layer of a chunk + use std::num::NonZeroU16; use anyhow::{Context, Result}; @@ -10,6 +12,7 @@ use crate::{ types::*, }; +/// Height (Y coordinate) of a block #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct BlockHeight(pub i32); @@ -28,27 +31,52 @@ impl BlockHeight { } } +/// Array optionally storing a [BlockType] for each coordinate of a chunk pub type BlockArray = LayerBlockArray>; + +/// Array optionally storing a biome index for each coordinate of a chunk +/// +/// The entries refer to a biome list generated with the top layer data. +/// Indices are stored incremented by 1 to allow using a [NonZeroU16]. pub type BiomeArray = LayerBlockArray>; + +/// Array storing a block light value for each coordinate for a chunk pub type BlockLightArray = LayerBlockArray; + +/// Array optionally storing a depth value for each coordinate for a chunk 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, + /// The biome type of the referenced entry biome: &'a mut Option, + /// The block light of the referenced entry block_light: &'a mut u8, + /// The depth value of the referenced entry depth: &'a mut Option, } impl<'a> LayerEntry<'a> { + /// 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 + /// has already been filled. fn is_empty(&self) -> bool { self.block.is_none() } + /// Returns true if the entry has been filled including its depth (an opaque non-water block has been + /// encountered) fn done(&self) -> bool { self.depth.is_some() } + /// Fills in the LayerEntry + /// + /// Checks whether the passed coordinates point at an opaque or non-water block and + /// fills in the entry accordingly. Returns true when the block has been filled including its depth. fn fill( &mut self, biome_list: &mut IndexSet, @@ -90,15 +118,24 @@ impl<'a> LayerEntry<'a> { } } +/// Top layer data +/// +/// A LayerData stores block type, biome, block light and depth data for +/// each coordinate of a chunk. #[derive(Debug, Default)] pub struct LayerData { + /// Block type data pub blocks: Box, + /// Biome data pub biomes: Box, + /// Block light data pub block_light: Box, + /// Depth data pub depths: Box, } impl LayerData { + /// Builds a [LayerEntry] referencing the LayerData at a given coordinate pair fn entry(&mut self, coords: LayerBlockCoords) -> LayerEntry { LayerEntry { block: &mut self.blocks[coords], @@ -109,13 +146,14 @@ impl LayerData { } } -/// Fills in a [BlockInfoArray] with the information of the chunk's top +/// Fills in a [LayerData] with the information of the chunk's top /// block layer /// /// For each (X, Z) coordinate pair, the topmost opaque block is /// determined as the block that should be visible on the rendered /// map. For water blocks, the height of the first non-water block -/// is additionally filled in as the water depth. +/// is additionally filled in as the water depth (the block height is +/// used as depth otherwise). pub fn top_layer(biome_list: &mut IndexSet, chunk: &Chunk) -> Result> { use BLOCKS_PER_CHUNK as N; diff --git a/src/world/mod.rs b/src/world/mod.rs index 9879066..57aa7ed 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,3 +1,5 @@ +//! Data structures describing Minecraft save data + pub mod chunk; pub mod de; pub mod layer; diff --git a/src/world/section.rs b/src/world/section.rs index 5f6553d..8f47216 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -1,3 +1,8 @@ +//! Higher-level interfaces to section data +//! +//! The data types in this module attempt to provide interfaces abstracting +//! over different data versions as much as possible. + use std::fmt::Debug; use anyhow::{bail, Context, Result}; @@ -9,6 +14,14 @@ use crate::{ types::*, }; +use BLOCKS_PER_CHUNK as N; +/// Maximum height of pre-1.18 levels +const HEIGHT: usize = 256; +/// Number of biome entries per chunk in each direction +const BN: usize = N >> 2; +/// Pre-1.18 height of level measured in 4-block spans (resolution of 1.15+ biome data) +const BHEIGHT: usize = HEIGHT >> 2; + /// Determine the number of bits required for indexing into a palette of a given length /// /// This is basically a base-2 logarithm, with clamping to a minimum value and @@ -29,20 +42,31 @@ 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>; } /// Minecraft v1.13+ section block data #[derive(Debug)] 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>, + /// Number of bits per block in *block_states* bits: u8, + /// Set to true if packed block entries in *block_states* are aligned to i64 + /// + /// In older data formats, entries are unaligned and a single block can span + /// two i64 entries. aligned_blocks: bool, } impl<'a> SectionV1_13<'a> { /// Constructs a new [SectionV1_13] from deserialized data structures + /// + /// The block IDs in the section's palette are resolved to their [BlockType]s + /// to allow for faster lookup later. pub fn new( data_version: u32, block_states: Option<&'a [i64]>, @@ -127,16 +151,21 @@ impl<'a> Section for SectionV1_13<'a> { /// Pre-1.13 section block data #[derive(Debug)] pub struct SectionV0<'a> { + /// Block type data + /// + /// Each i8 entry corresponds to a block in the 16x16x16 section blocks: &'a [i8], + /// Block damage/subtype data + /// + /// Uses 4 bits for each block in the 16x16x16 section data: &'a [i8], + /// Used to look up block type IDs block_types: &'a BlockTypes, } impl<'a> SectionV0<'a> { /// Constructs a new [SectionV0] from deserialized data structures pub fn new(blocks: &'a [i8], data: &'a [i8], block_types: &'a BlockTypes) -> Result { - use BLOCKS_PER_CHUNK as N; - if blocks.len() != N * N * N { bail!("Invalid section block data"); } @@ -171,6 +200,7 @@ impl<'a> Section for SectionV0<'a> { /// 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>; } @@ -181,13 +211,21 @@ pub trait Biomes: Debug { /// v1.13+ block data. #[derive(Debug)] pub struct BiomesV1_18<'a> { + /// Packed biome data + /// + /// Each entry specifies the biome of a 4x4x4 block area. + /// + /// Unlike block type data in [SectionV1_13], biome data is always aligned + /// to whole i64 values. biomes: Option<&'a [i64]>, + /// Biome palette indexed by entries encoded in *biomes* palette: Vec>, + /// Number of bits used for each entry in *biomes* bits: u8, } impl<'a> BiomesV1_18<'a> { - /// Constructs a new [BiomesV18] from deserialized data structures + /// Constructs a new [BiomesV1_18] from deserialized data structures pub fn new( biomes: Option<&'a [i64]>, palette: &'a [String], @@ -223,9 +261,6 @@ impl<'a> BiomesV1_18<'a> { /// Looks up the block type palette index at the given coordinates fn palette_index_at(&self, coords: SectionBlockCoords) -> usize { - const N: usize = BLOCKS_PER_CHUNK; - const BN: usize = N >> 2; - let Some(biomes) = self.biomes else { return 0; }; @@ -262,28 +297,31 @@ impl<'a> Biomes for BiomesV1_18<'a> { /// different pre-v1.18 Minecraft versions #[derive(Debug)] enum BiomesV0Data<'a> { + /// Biome data stored as IntArray in 1.15+ format + /// + /// Minecraft 1.15 switched to 3-dimensional biome information, but reduced + /// the resolution to only use one entry for every 4x4x4 block area. IntArrayV15(&'a fastnbt::IntArray), + /// Biome data stored as IntArray in some pre-1.15 versions IntArrayV0(&'a fastnbt::IntArray), + /// Biome data stored as ByteArray in some pre-1.15 versions ByteArray(&'a fastnbt::ByteArray), } /// Pre-v1.18 section biome data #[derive(Debug)] pub struct BiomesV0<'a> { + /// Biome data from save data data: BiomesV0Data<'a>, + /// Used to look up biome IDs biome_types: &'a BiomeTypes, } impl<'a> BiomesV0<'a> { /// Constructs a new [BiomesV0] from deserialized data structures pub fn new(biomes: Option<&'a de::BiomesV0>, biome_types: &'a BiomeTypes) -> Result { - const N: usize = BLOCKS_PER_CHUNK; - const MAXY: usize = 256; - const BN: usize = N >> 2; - const BMAXY: usize = MAXY >> 2; - let data = match biomes { - Some(de::BiomesV0::IntArray(data)) if data.len() == BN * BN * BMAXY => { + Some(de::BiomesV0::IntArray(data)) if data.len() == BN * BN * BHEIGHT => { BiomesV0Data::IntArrayV15(data) } Some(de::BiomesV0::IntArray(data)) if data.len() == N * N => { @@ -302,16 +340,12 @@ impl<'a> Biomes for BiomesV0<'a> { fn biome_at(&self, section: SectionY, coords: SectionBlockCoords) -> Result> { let id = match self.data { BiomesV0Data::IntArrayV15(data) => { - const N: usize = BLOCKS_PER_CHUNK; - const MAXY: usize = 256; - const BN: usize = N >> 2; - let LayerBlockCoords { x, z } = coords.xz; let y = section .0 .checked_mul(BLOCKS_PER_CHUNK as i32) .and_then(|y| y.checked_add_unsigned(coords.y.0.into())) - .filter(|&height| height >= 0 && (height as usize) < MAXY) + .filter(|&height| height >= 0 && (height as usize) < HEIGHT) .context("Y coordinate out of range")? as usize; let offset = (y >> 2) * BN * BN + (z.0 >> 2) as usize * BN + (x.0 >> 2) as usize; let id = data[offset] as u32; @@ -327,12 +361,13 @@ impl<'a> Biomes for BiomesV0<'a> { } } +/// Wrapper around chunk block light data array #[derive(Debug, Clone, Copy)] pub struct BlockLight<'a>(Option<&'a [i8]>); impl<'a> BlockLight<'a> { + /// Creates a new [BlockLight], checking validity pub fn new(block_light: Option<&'a [i8]>) -> Result { - use BLOCKS_PER_CHUNK as N; if let Some(block_light) = block_light { if block_light.len() != N * N * N / 2 { bail!("Invalid section block light data"); @@ -341,6 +376,7 @@ impl<'a> BlockLight<'a> { Ok(BlockLight(block_light)) } + /// Returns the block light value at the given coordinates pub fn block_light_at(&self, coords: SectionBlockCoords) -> u8 { let Some(block_light) = self.0 else { return 0; From 204d0d06d510b5ca957205de381d6a8e78f228e8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 12:20:57 +0200 Subject: [PATCH 236/460] resource/biomes: add Minecraft 1.20 support Add the new Cherry Grove biome. --- src/resource/biomes.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/resource/biomes.rs b/src/resource/biomes.rs index 54859df..61f8339 100644 --- a/src/resource/biomes.rs +++ b/src/resource/biomes.rs @@ -130,6 +130,13 @@ pub const BIOMES: &[(&str, Biome)] = { ("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)), ( From 3cb65ec70e4ba6e4237b3820a28b43d8e67ad7e5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 13:41:37 +0200 Subject: [PATCH 237/460] resource/block_types: update for Minecraft 1.20 --- resource/blocks.json | 134 ++++++++++ src/resource/block_types.rs | 494 +++++++++++++++++++++++++++++++++++- 2 files changed, 626 insertions(+), 2 deletions(-) diff --git a/resource/blocks.json b/resource/blocks.json index cfb908f..8e87750 100644 --- a/resource/blocks.json +++ b/resource/blocks.json @@ -9,6 +9,7 @@ "acacia_fence_gate": { "texture": "acacia_planks" }, + "acacia_hanging_sign": null, "acacia_leaves": { "foliage": true }, @@ -30,6 +31,7 @@ "texture": "acacia_planks" }, "acacia_trapdoor": {}, + "acacia_wall_hanging_sign": null, "acacia_wall_sign": null, "acacia_wood": { "texture": "acacia_log" @@ -69,7 +71,44 @@ "bamboo": { "texture": "bamboo_stalk" }, + "bamboo_block": { + "texture": "bamboo_block_top" + }, + "bamboo_button": null, + "bamboo_door": { + "texture": "bamboo_door_top" + }, + "bamboo_fence": { + "texture": "bamboo_planks" + }, + "bamboo_fence_gate": { + "texture": "bamboo_planks" + }, + "bamboo_hanging_sign": null, + "bamboo_mosaic": {}, + "bamboo_mosaic_slab": { + "texture": "bamboo_mosaic" + }, + "bamboo_mosaic_stairs": { + "texture": "bamboo_mosaic" + }, + "bamboo_planks": {}, + "bamboo_pressure_plate": { + "texture": "bamboo_planks" + }, "bamboo_sapling": null, + "bamboo_sign": { + "texture": "bamboo_planks" + }, + "bamboo_slab": { + "texture": "bamboo_planks" + }, + "bamboo_stairs": { + "texture": "bamboo_planks" + }, + "bamboo_trapdoor": {}, + "bamboo_wall_hanging_sign": null, + "bamboo_wall_sign": null, "barrel": { "texture": "barrel_top" }, @@ -105,6 +144,7 @@ "birch_fence_gate": { "texture": "birch_planks" }, + "birch_hanging_sign": null, "birch_leaves": { "birch": true }, @@ -126,6 +166,7 @@ "texture": "birch_planks" }, "birch_trapdoor": {}, + "birch_wall_hanging_sign": null, "birch_wall_sign": null, "birch_wood": { "texture": "birch_log" @@ -246,6 +287,9 @@ "texture": "cake_top" }, "calcite": {}, + "calibrated_sculk_sensor": { + "texture": "calibrated_sculk_sensor_top" + }, "campfire": { "texture": "campfire_log_lit" }, @@ -272,12 +316,50 @@ "chain_command_block": { "texture": "chain_command_block_side" }, + "cherry_button": null, + "cherry_door": { + "texture": "cherry_door_top" + }, + "cherry_fence": { + "texture": "cherry_planks" + }, + "cherry_fence_gate": { + "texture": "cherry_planks" + }, + "cherry_hanging_sign": null, + "cherry_leaves": {}, + "cherry_log": { + "texture": "cherry_log_top" + }, + "cherry_planks": {}, + "cherry_pressure_plate": { + "texture": "cherry_planks" + }, + "cherry_sapling": null, + "cherry_sign": { + "texture": "cherry_planks" + }, + "cherry_slab": { + "texture": "cherry_planks" + }, + "cherry_stairs": { + "texture": "cherry_planks" + }, + "cherry_trapdoor": {}, + "cherry_wall_hanging_sign": null, + "cherry_wall_sign": null, + "cherry_wood": { + "texture": "cherry_log" + }, "chest": { "texture": "oak_planks" }, "chipped_anvil": { "texture": "chipped_anvil_top" }, + "chiseled_bookshelf": { + "texture": "chiseled_bookshelf_top" + }, "chiseled_deepslate": {}, "chiseled_nether_bricks": {}, "chiseled_polished_blackstone": {}, @@ -351,6 +433,7 @@ "texture": "crimson_planks" }, "crimson_fungus": null, + "crimson_hanging_sign": null, "crimson_hyphae": { "texture": "crimson_stem" }, @@ -373,6 +456,7 @@ "texture": "crimson_stem_top" }, "crimson_trapdoor": {}, + "crimson_wall_hanging_sign": null, "crimson_wall_sign": null, "crying_obsidian": {}, "cut_copper": {}, @@ -428,6 +512,7 @@ "dark_oak_fence_gate": { "texture": "dark_oak_planks" }, + "dark_oak_hanging_sign": null, "dark_oak_leaves": { "foliage": true }, @@ -449,6 +534,7 @@ "texture": "dark_oak_planks" }, "dark_oak_trapdoor": {}, + "dark_oak_wall_hanging_sign": null, "dark_oak_wall_sign": null, "dark_oak_wood": { "texture": "dark_oak_log" @@ -484,6 +570,9 @@ "dead_tube_coral_block": {}, "dead_tube_coral_fan": null, "dead_tube_coral_wall_fan": null, + "decorated_pot": { + "texture": "flower_pot" + }, "deepslate": {}, "deepslate_brick_slab": { "texture": "deepslate_bricks" @@ -743,6 +832,7 @@ "jungle_fence_gate": { "texture": "jungle_planks" }, + "jungle_hanging_sign": null, "jungle_leaves": { "foliage": true }, @@ -764,6 +854,7 @@ "texture": "jungle_planks" }, "jungle_trapdoor": {}, + "jungle_wall_hanging_sign": null, "jungle_wall_sign": null, "jungle_wood": { "texture": "jungle_log" @@ -900,6 +991,7 @@ "mangrove_fence_gate": { "texture": "mangrove_planks" }, + "mangrove_hanging_sign": null, "mangrove_leaves": { "foliage": true }, @@ -924,6 +1016,7 @@ "texture": "mangrove_planks" }, "mangrove_trapdoor": {}, + "mangrove_wall_hanging_sign": null, "mangrove_wall_sign": null, "mangrove_wood": { "texture": "mangrove_log" @@ -1012,6 +1105,7 @@ "oak_fence_gate": { "texture": "oak_planks" }, + "oak_hanging_sign": null, "oak_leaves": { "foliage": true }, @@ -1033,6 +1127,7 @@ "texture": "oak_planks" }, "oak_trapdoor": {}, + "oak_wall_hanging_sign": null, "oak_wall_sign": null, "oak_wood": { "texture": "oak_log" @@ -1085,6 +1180,8 @@ "petrified_oak_slab": { "texture": "oak_planks" }, + "piglin_head": null, + "piglin_wall_head": null, "pink_banner": null, "pink_bed": null, "pink_candle": null, @@ -1097,6 +1194,7 @@ "pink_concrete": {}, "pink_concrete_powder": {}, "pink_glazed_terracotta": {}, + "pink_petals": null, "pink_shulker_box": {}, "pink_stained_glass": {}, "pink_stained_glass_pane": { @@ -1112,6 +1210,12 @@ "piston_head": { "texture": "piston_top" }, + "pitcher_crop": { + "texture": "pitcher_crop_top" + }, + "pitcher_plant": { + "texture": "pitcher_crop_top_stage_4" + }, "player_head": null, "player_wall_head": null, "podzol": { @@ -1209,6 +1313,9 @@ "potted_cactus": { "texture": "cactus_top" }, + "potted_cherry_sapling": { + "texture": "cherry_sapling" + }, "potted_cornflower": { "texture": "cornflower" }, @@ -1267,6 +1374,9 @@ "potted_spruce_sapling": { "texture": "spruce_sapling" }, + "potted_torchflower": { + "texture": "torchflower" + }, "potted_warped_fungus": { "texture": "warped_fungus" }, @@ -1496,6 +1606,9 @@ "smooth_stone_slab": { "texture": "smooth_stone" }, + "sniffer_egg": { + "texture": "sniffer_egg_not_cracked_top" + }, "snow": {}, "snow_block": { "texture": "snow" @@ -1524,6 +1637,7 @@ "spruce_fence_gate": { "texture": "spruce_planks" }, + "spruce_hanging_sign": null, "spruce_leaves": { "spruce": true }, @@ -1545,6 +1659,7 @@ "texture": "spruce_planks" }, "spruce_trapdoor": {}, + "spruce_wall_hanging_sign": null, "spruce_wall_sign": null, "spruce_wood": { "texture": "spruce_log" @@ -1582,12 +1697,21 @@ "stripped_acacia_wood": { "texture": "stripped_acacia_log" }, + "stripped_bamboo_block": { + "texture": "stripped_bamboo_block_top" + }, "stripped_birch_log": { "texture": "stripped_birch_log_top" }, "stripped_birch_wood": { "texture": "stripped_birch_log" }, + "stripped_cherry_log": { + "texture": "stripped_cherry_log_top" + }, + "stripped_cherry_wood": { + "texture": "stripped_cherry_log" + }, "stripped_crimson_hyphae": { "texture": "stripped_crimson_stem" }, @@ -1636,6 +1760,12 @@ "sunflower": { "texture": "sunflower_front" }, + "suspicious_gravel": { + "texture": "suspicious_gravel_0" + }, + "suspicious_sand": { + "texture": "suspicious_sand_0" + }, "sweet_berry_bush": { "texture": "sweet_berry_bush_stage3" }, @@ -1655,6 +1785,8 @@ "texture": "tnt_top" }, "torch": null, + "torchflower": null, + "torchflower_crop": null, "trapped_chest": { "texture": "oak_planks" }, @@ -1688,6 +1820,7 @@ "texture": "warped_planks" }, "warped_fungus": null, + "warped_hanging_sign": null, "warped_hyphae": { "texture": "warped_stem" }, @@ -1710,6 +1843,7 @@ "texture": "warped_stem_top" }, "warped_trapdoor": {}, + "warped_wall_hanging_sign": null, "warped_wall_sign": null, "warped_wart_block": {}, "water": { diff --git a/src/resource/block_types.rs b/src/resource/block_types.rs index 467cf7a..68a08c0 100644 --- a/src/resource/block_types.rs +++ b/src/resource/block_types.rs @@ -31,6 +31,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([168, 90, 50]), }, ), + ( + "acacia_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "acacia_leaves", BlockType { @@ -94,6 +101,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([156, 87, 51]), }, ), + ( + "acacia_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "acacia_wall_sign", BlockType { @@ -227,6 +241,83 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([93, 144, 19]), }, ), + ( + "bamboo_block", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([139, 141, 62]), + }, + ), + ( + "bamboo_button", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "bamboo_door", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([191, 171, 81]), + }, + ), + ( + "bamboo_fence", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "bamboo_mosaic", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + ), + ( + "bamboo_mosaic_slab", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + ), + ( + "bamboo_mosaic_stairs", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([190, 170, 78]), + }, + ), + ( + "bamboo_planks", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), ( "bamboo_sapling", BlockType { @@ -234,6 +325,48 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([0, 0, 0]), }, ), + ( + "bamboo_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_slab", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_stairs", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 173, 80]), + }, + ), + ( + "bamboo_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([198, 179, 85]), + }, + ), + ( + "bamboo_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "bamboo_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "barrel", BlockType { @@ -339,6 +472,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([192, 175, 121]), }, ), + ( + "birch_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "birch_leaves", BlockType { @@ -402,6 +542,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([207, 194, 157]), }, ), + ( + "birch_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "birch_wall_sign", BlockType { @@ -913,6 +1060,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([223, 224, 220]), }, ), + ( + "calibrated_sculk_sensor", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([27, 79, 100]), + }, + ), ( "campfire", BlockType { @@ -997,6 +1151,125 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([131, 161, 147]), }, ), + ( + "cherry_button", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "cherry_door", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([223, 170, 164]), + }, + ), + ( + "cherry_fence", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_fence_gate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "cherry_leaves", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([229, 172, 194]), + }, + ), + ( + "cherry_log", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([185, 141, 137]), + }, + ), + ( + "cherry_planks", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_pressure_plate", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_sapling", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "cherry_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_slab", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_stairs", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_trapdoor", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([226, 178, 172]), + }, + ), + ( + "cherry_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "cherry_wall_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "cherry_wood", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([54, 33, 44]), + }, + ), ( "chest", BlockType { @@ -1011,6 +1284,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([72, 72, 72]), }, ), + ( + "chiseled_bookshelf", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 144, 88]), + }, + ), ( "chiseled_deepslate", BlockType { @@ -1312,6 +1592,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([0, 0, 0]), }, ), + ( + "crimson_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "crimson_hyphae", BlockType { @@ -1382,6 +1669,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([103, 50, 72]), }, ), + ( + "crimson_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "crimson_wall_sign", BlockType { @@ -1585,6 +1879,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([66, 43, 20]), }, ), + ( + "dark_oak_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "dark_oak_leaves", BlockType { @@ -1648,6 +1949,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([75, 49, 23]), }, ), + ( + "dark_oak_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "dark_oak_wall_sign", BlockType { @@ -1837,6 +2145,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([0, 0, 0]), }, ), + ( + "decorated_pot", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([124, 68, 53]), + }, + ), ( "deepslate", BlockType { @@ -2817,6 +3132,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([160, 115, 80]), }, ), + ( + "jungle_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "jungle_leaves", BlockType { @@ -2880,6 +3202,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([152, 110, 77]), }, ), + ( + "jungle_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "jungle_wall_sign", BlockType { @@ -3461,6 +3790,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([117, 54, 48]), }, ), + ( + "mangrove_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "mangrove_leaves", BlockType { @@ -3531,6 +3867,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([110, 46, 42]), }, ), + ( + "mangrove_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "mangrove_wall_sign", BlockType { @@ -3825,6 +4168,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([162, 130, 78]), }, ), + ( + "oak_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "oak_leaves", BlockType { @@ -3888,6 +4238,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([124, 99, 56]), }, ), + ( + "oak_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "oak_wall_sign", BlockType { @@ -4098,6 +4455,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([162, 130, 78]), }, ), + ( + "piglin_head", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "piglin_wall_head", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "pink_banner", BlockType { @@ -4154,6 +4525,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([235, 154, 181]), }, ), + ( + "pink_petals", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "pink_shulker_box", BlockType { @@ -4217,6 +4595,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([153, 127, 85]), }, ), + ( + "pitcher_crop", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([193, 165, 103]), + }, + ), + ( + "pitcher_plant", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([122, 144, 189]), + }, + ), ( "player_head", BlockType { @@ -4490,6 +4882,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([85, 127, 43]), }, ), + ( + "potted_cherry_sapling", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([164, 117, 143]), + }, + ), ( "potted_cornflower", BlockType { @@ -4623,6 +5022,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([44, 60, 36]), }, ), + ( + "potted_torchflower", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([100, 101, 77]), + }, + ), ( "potted_warped_fungus", BlockType { @@ -4788,7 +5194,7 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "purple_glazed_terracotta", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([109, 48, 152]), + color: Color([109, 47, 152]), }, ), ( @@ -5229,7 +5635,7 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ "scaffolding", BlockType { flags: make_bitflags!(BlockFlag::{Opaque}), - color: Color([174, 134, 80]), + color: Color([170, 131, 73]), }, ), ( @@ -5442,6 +5848,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([158, 158, 158]), }, ), + ( + "sniffer_egg", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([135, 105, 67]), + }, + ), ( "snow", BlockType { @@ -5554,6 +5967,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([114, 84, 48]), }, ), + ( + "spruce_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "spruce_leaves", BlockType { @@ -5617,6 +6037,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([103, 79, 47]), }, ), + ( + "spruce_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "spruce_wall_sign", BlockType { @@ -5722,6 +6149,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([174, 92, 59]), }, ), + ( + "stripped_bamboo_block", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([178, 158, 72]), + }, + ), ( "stripped_birch_log", BlockType { @@ -5736,6 +6170,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([196, 176, 118]), }, ), + ( + "stripped_cherry_log", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([221, 164, 157]), + }, + ), + ( + "stripped_cherry_wood", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([215, 145, 148]), + }, + ), ( "stripped_crimson_hyphae", BlockType { @@ -5862,6 +6310,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([246, 196, 54]), }, ), + ( + "suspicious_gravel", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([129, 125, 124]), + }, + ), + ( + "suspicious_sand", + BlockType { + flags: make_bitflags!(BlockFlag::{Opaque}), + color: Color([217, 204, 159]), + }, + ), ( "sweet_berry_bush", BlockType { @@ -5918,6 +6380,20 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([0, 0, 0]), }, ), + ( + "torchflower", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), + ( + "torchflower_crop", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "trapped_chest", BlockType { @@ -6065,6 +6541,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([0, 0, 0]), }, ), + ( + "warped_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "warped_hyphae", BlockType { @@ -6135,6 +6618,13 @@ pub const BLOCK_TYPES: &[(&str, BlockType)] = &[ color: Color([47, 119, 111]), }, ), + ( + "warped_wall_hanging_sign", + BlockType { + flags: make_bitflags!(BlockFlag::{}), + color: Color([0, 0, 0]), + }, + ), ( "warped_wall_sign", BlockType { From 9ec1c03ce1ce15f8e0671d941725e84d29c2efb2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 14:15:29 +0200 Subject: [PATCH 238/460] Only name library crate rather than whole package "minedmap-core" --- Cargo.lock | 2 +- Cargo.toml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06f1283..0224949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -553,7 +553,7 @@ dependencies = [ ] [[package]] -name = "minedmap-core" +name = "minedmap" version = "0.1.0" dependencies = [ "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 664b976..bbbc171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,12 @@ [package] -name = "minedmap-core" +name = "minedmap" version = "0.1.0" edition = "2021" license = "MIT" default-run = "minedmap" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "minedmap_core" [dependencies] anyhow = "1.0.68" From 09399f5ae951aa578375826930f7d600899797e6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 16:28:20 +0200 Subject: [PATCH 239/460] Update dependencies --- Cargo.lock | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0224949..17c6122 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" @@ -167,9 +167,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.21" +version = "4.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3" dependencies = [ "clap_builder", "clap_derive", @@ -178,9 +178,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.21" +version = "4.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98" dependencies = [ "anstream", "anstyle", @@ -356,9 +356,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "libz-ng-sys", @@ -687,9 +687,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" -version = "0.17.9" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -709,9 +709,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -853,9 +853,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.28" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -864,9 +864,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.31.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "parking_lot", @@ -902,9 +902,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -917,45 +917,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "zstd" From 248a64103517bc1a43eb694cbf05a58aba99df88 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 16:28:10 +0200 Subject: [PATCH 240/460] Restructure crates Get rid of the arbitrary bin/lib split and instead move as much as possible into the bin crate, which becomes the main crate again. The types and NBT handling are moved into separate crates, so they can be reused by nbtdump and regiondump. --- Cargo.lock | 25 ++++++++++++++++--- Cargo.toml | 13 +++++----- crates/nbt/Cargo.toml | 17 +++++++++++++ {src/io => crates/nbt/src}/data.rs | 0 crates/nbt/src/lib.rs | 7 ++++++ {src/io => crates/nbt/src}/region.rs | 2 +- crates/types/Cargo.toml | 10 ++++++++ src/types.rs => crates/types/src/lib.rs | 14 +++++++++++ src/bin/nbtdump.rs | 2 +- src/bin/regiondump.rs | 2 +- src/{bin/minedmap => core}/common.rs | 2 +- src/{bin/minedmap => core}/metadata_writer.rs | 7 ++---- src/{bin/minedmap/main.rs => core/mod.rs} | 10 +++----- src/{bin/minedmap => core}/region_group.rs | 0 .../minedmap => core}/region_processor.rs | 19 ++++++-------- src/{bin/minedmap => core}/tile_mipmapper.rs | 6 ++--- src/{bin/minedmap => core}/tile_renderer.rs | 15 +++++------ src/io/mod.rs | 2 -- src/lib.rs | 10 -------- src/main.rs | 19 ++++++++++++++ src/resource/mod.rs | 1 + 21 files changed, 121 insertions(+), 62 deletions(-) create mode 100644 crates/nbt/Cargo.toml rename {src/io => crates/nbt/src}/data.rs (100%) create mode 100644 crates/nbt/src/lib.rs rename {src/io => crates/nbt/src}/region.rs (99%) create mode 100644 crates/types/Cargo.toml rename src/types.rs => crates/types/src/lib.rs (96%) rename src/{bin/minedmap => core}/common.rs (98%) rename src/{bin/minedmap => core}/metadata_writer.rs (94%) rename src/{bin/minedmap/main.rs => core/mod.rs} (87%) rename src/{bin/minedmap => core}/region_group.rs (100%) rename src/{bin/minedmap => core}/region_processor.rs (96%) rename src/{bin/minedmap => core}/tile_mipmapper.rs (98%) rename src/{bin/minedmap => core}/tile_renderer.rs (98%) delete mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 17c6122..2b755fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,17 +558,16 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", - "bytemuck", "clap", "enumflags2", "fastnbt", - "flate2", "futures-util", "glam", "image", "indexmap", - "itertools", "lru", + "minedmap-nbt", + "minedmap-types", "num-integer", "num_cpus", "rayon", @@ -579,6 +578,26 @@ dependencies = [ "zstd", ] +[[package]] +name = "minedmap-nbt" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytemuck", + "fastnbt", + "flate2", + "minedmap-types", + "serde", +] + +[[package]] +name = "minedmap-types" +version = "0.1.0" +dependencies = [ + "itertools", + "serde", +] + [[package]] name = "miniz_oxide" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index bbbc171..7c9ab32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["crates/*"] + [package] name = "minedmap" version = "0.1.0" @@ -5,23 +8,19 @@ edition = "2021" license = "MIT" default-run = "minedmap" -[lib] -name = "minedmap_core" - [dependencies] anyhow = "1.0.68" bincode = "1.3.3" -bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } enumflags2 = { version = "0.7.5", features = ["serde"] } fastnbt = "2.3.2" -flate2 = "1.0.25" futures-util = "0.3.28" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } -itertools = "0.11.0" lru = "0.11.0" +minedmap-nbt = { version = "0.1.0", path = "crates/nbt", default-features = false } +minedmap-types = { version = "0.1.0", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" @@ -33,4 +32,4 @@ zstd = "0.12.3" [features] default = ["zlib-ng"] -zlib-ng = ["flate2/zlib-ng"] +zlib-ng = ["minedmap-nbt/zlib-ng"] diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml new file mode 100644 index 0000000..ff1d7d2 --- /dev/null +++ b/crates/nbt/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "minedmap-nbt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +bytemuck = "1.13.1" +fastnbt = "2.4.4" +flate2 = "1.0.27" +minedmap-types = { version = "0.1.0", path = "../types" } +serde = "1.0.183" + +[features] +zlib-ng = ["flate2/zlib-ng"] diff --git a/src/io/data.rs b/crates/nbt/src/data.rs similarity index 100% rename from src/io/data.rs rename to crates/nbt/src/data.rs diff --git a/crates/nbt/src/lib.rs b/crates/nbt/src/lib.rs new file mode 100644 index 0000000..0b817b1 --- /dev/null +++ b/crates/nbt/src/lib.rs @@ -0,0 +1,7 @@ +//! MinedMap's of Minecraft NBT data and region files + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + +pub mod data; +pub mod region; diff --git a/src/io/region.rs b/crates/nbt/src/region.rs similarity index 99% rename from src/io/region.rs rename to crates/nbt/src/region.rs index 82f5604..8a52b9d 100644 --- a/src/io/region.rs +++ b/crates/nbt/src/region.rs @@ -10,7 +10,7 @@ use anyhow::{bail, Context, Result}; use flate2::read::ZlibDecoder; use serde::de::DeserializeOwned; -use crate::types::*; +use minedmap_types::*; /// Data block size of region data files /// diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml new file mode 100644 index 0000000..fae230b --- /dev/null +++ b/crates/types/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "minedmap-types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.11.0" +serde = "1.0.183" diff --git a/src/types.rs b/crates/types/src/lib.rs similarity index 96% rename from src/types.rs rename to crates/types/src/lib.rs index 045750b..2e4ea61 100644 --- a/src/types.rs +++ b/crates/types/src/lib.rs @@ -1,5 +1,8 @@ //! Common types used by MinedMap +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + use std::{ fmt::Debug, iter::FusedIterator, @@ -32,6 +35,7 @@ macro_rules! coord_type { /// Constructs a new value /// /// Will panic if the value is not in the valid range + #[inline] pub fn new>(value: T) -> Self { Self( value @@ -43,6 +47,7 @@ macro_rules! coord_type { } /// Returns an iterator over all possible values of the type + #[inline] pub fn iter() -> impl Iterator> + DoubleEndedIterator + ExactSizeIterator @@ -95,6 +100,7 @@ impl LayerBlockCoords { /// Many chunk data structures store block and biome data in the same /// order. This method computes the offset at which the data for the /// block at a given coordinate is stored. + #[inline] pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let x = self.x.0 as usize; @@ -112,12 +118,14 @@ pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); impl Index for LayerBlockArray { type Output = T; + #[inline] fn index(&self, index: LayerBlockCoords) -> &Self::Output { &self.0[index.z.0 as usize][index.x.0 as usize] } } impl IndexMut for LayerBlockArray { + #[inline] fn index_mut(&mut self, index: LayerBlockCoords) -> &mut Self::Output { &mut self.0[index.z.0 as usize][index.x.0 as usize] } @@ -138,6 +146,7 @@ impl SectionBlockCoords { /// Many chunk data structures store block and biome data in the same /// order. This method computes the offset at which the data for the /// block at a given coordinate is stored. + #[inline] pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let y = self.y.0 as usize; @@ -194,16 +203,19 @@ pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { /// Iterates over all possible chunk coordinate pairs used as [ChunkArray] keys + #[inline] pub fn keys() -> impl Iterator + Clone + Debug { iproduct!(ChunkZ::iter(), ChunkX::iter()).map(|(z, x)| ChunkCoords { x, z }) } /// Iterates over all values stored in the [ChunkArray] + #[inline] pub fn values(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| &self[k]) } /// Iterates over pairs of chunk coordinate pairs and corresponding stored values + #[inline] pub fn iter(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| (k, &self[k])) } @@ -212,12 +224,14 @@ impl ChunkArray { impl Index for ChunkArray { type Output = T; + #[inline] fn index(&self, index: ChunkCoords) -> &Self::Output { &self.0[index.z.0 as usize][index.x.0 as usize] } } impl IndexMut for ChunkArray { + #[inline] fn index_mut(&mut self, index: ChunkCoords) -> &mut Self::Output { &mut self.0[index.z.0 as usize][index.x.0 as usize] } diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index da5e502..a83a199 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -18,7 +18,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let value: fastnbt::Value = minedmap_core::io::data::from_file(args.file.as_path())?; + let value: fastnbt::Value = minedmap_nbt::data::from_file(args.file.as_path())?; println!("{:#x?}", value); Ok(()) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 21351f7..c8e87b4 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -18,7 +18,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - minedmap_core::io::region::from_file(args.file.as_path())?.foreach_chunk( + minedmap_nbt::region::from_file(args.file.as_path())?.foreach_chunk( |coords, value: fastnbt::Value| { println!("Chunk {:?}: {:#x?}", coords, value); Ok(()) diff --git a/src/bin/minedmap/common.rs b/src/core/common.rs similarity index 98% rename from src/bin/minedmap/common.rs rename to src/core/common.rs index 4183b64..a6d9a44 100644 --- a/src/bin/minedmap/common.rs +++ b/src/core/common.rs @@ -9,7 +9,7 @@ use std::{ use indexmap::IndexSet; use serde::{Deserialize, Serialize}; -use super::core::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; +use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; /// MinedMap data version number /// diff --git a/src/bin/minedmap/metadata_writer.rs b/src/core/metadata_writer.rs similarity index 94% rename from src/bin/minedmap/metadata_writer.rs rename to src/core/metadata_writer.rs index 2ba6038..5783356 100644 --- a/src/bin/minedmap/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -3,10 +3,7 @@ use anyhow::{Context, Result}; use serde::Serialize; -use super::{ - common::*, - core::{self, io::fs, world::de}, -}; +use crate::{core::common::*, io::fs, world::de}; /// Minimum and maximum X and Z tile coordinates for a mipmap level #[derive(Debug, Serialize)] @@ -101,7 +98,7 @@ impl<'a> MetadataWriter<'a> { /// Reads and deserializes the `level.dat` of the Minecraft save data fn read_level_dat(&self) -> Result { - core::io::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") + crate::nbt::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") } /// Generates [Spawn] data from a [de::LevelDat] diff --git a/src/bin/minedmap/main.rs b/src/core/mod.rs similarity index 87% rename from src/bin/minedmap/main.rs rename to src/core/mod.rs index 925a38b..a94cf2c 100644 --- a/src/bin/minedmap/main.rs +++ b/src/core/mod.rs @@ -1,7 +1,4 @@ -//! The minedmap generator renders map tile images from Minecraft save data - -#![warn(missing_docs)] -#![warn(clippy::missing_docs_in_private_items)] +//! Core functions of the MinedMap CLI mod common; mod metadata_writer; @@ -10,8 +7,6 @@ mod region_processor; mod tile_mipmapper; mod tile_renderer; -use minedmap_core as core; - use std::path::PathBuf; use anyhow::{Context, Result}; @@ -46,7 +41,8 @@ fn setup_threads(num_threads: usize) -> Result<()> { .context("Failed to configure thread pool") } -fn main() -> Result<()> { +/// MinedMap CLI main function +pub fn cli() -> Result<()> { let args = Args::parse(); let config = Config::new(&args); diff --git a/src/bin/minedmap/region_group.rs b/src/core/region_group.rs similarity index 100% rename from src/bin/minedmap/region_group.rs rename to src/core/region_group.rs diff --git a/src/bin/minedmap/region_processor.rs b/src/core/region_processor.rs similarity index 96% rename from src/bin/minedmap/region_processor.rs rename to src/core/region_processor.rs index 7168ebd..6e32d94 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/core/region_processor.rs @@ -6,17 +6,14 @@ use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use super::{ - common::*, - core::{ +use super::common::*; +use crate::{ + io::{fs, storage}, + resource::{self, Biome}, + types::*, + world::{ self, - io::{fs, storage}, - resource::{self, Biome}, - types::*, - world::{ - self, - layer::{self, LayerData}, - }, + layer::{self, LayerData}, }, }; @@ -157,7 +154,7 @@ impl<'a> RegionProcessor<'a> { println!("Processing region r.{}.{}.mca", coords.x, coords.z); - core::io::region::from_file(path)?.foreach_chunk( + crate::nbt::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData { blocks, diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/core/tile_mipmapper.rs similarity index 98% rename from src/bin/minedmap/tile_mipmapper.rs rename to src/core/tile_mipmapper.rs index 59c2880..52fff09 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -3,10 +3,8 @@ use anyhow::{Context, Result}; use rayon::prelude::*; -use super::{ - common::*, - core::{io::fs, types::*}, -}; +use super::common::*; +use crate::{io::fs, types::*}; /// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'a> { diff --git a/src/bin/minedmap/tile_renderer.rs b/src/core/tile_renderer.rs similarity index 98% rename from src/bin/minedmap/tile_renderer.rs rename to src/core/tile_renderer.rs index d5b7644..c26c559 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -13,15 +13,12 @@ use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; -use super::{ - common::*, - core::{ - io::{fs, storage}, - resource::{block_color, needs_biome}, - types::*, - util::coord_offset, - }, - region_group::RegionGroup, +use super::{common::*, region_group::RegionGroup}; +use crate::{ + io::{fs, storage}, + resource::{block_color, needs_biome}, + types::*, + util::coord_offset, }; /// Type for referencing loaded [ProcessedRegion] data diff --git a/src/io/mod.rs b/src/io/mod.rs index 590ca2a..bfe2a2c 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,6 +1,4 @@ //! Input/output functions -pub mod data; pub mod fs; -pub mod region; pub mod storage; diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 14d97f9..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Common library for MinedMap generator and dump utilities - -#![warn(missing_docs)] -#![warn(clippy::missing_docs_in_private_items)] - -pub mod io; -pub mod resource; -pub mod types; -pub mod util; -pub mod world; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9bbe0ab --- /dev/null +++ b/src/main.rs @@ -0,0 +1,19 @@ +//! The minedmap generator renders map tile images from Minecraft save data + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + +mod core; +mod io; +mod resource; +mod util; +mod world; + +use minedmap_nbt as nbt; +use minedmap_types as types; + +use anyhow::Result; + +fn main() -> Result<()> { + core::cli() +} diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 459e783..a0854c5 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -46,6 +46,7 @@ pub struct BlockType { impl BlockType { /// Checks whether a block type has a given [BlockFlag] set + #[inline] pub fn is(&self, flag: BlockFlag) -> bool { self.flags.contains(flag) } From 228f31c568d447d7e214654948fb6c2dfd15eaee Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 16:55:10 +0200 Subject: [PATCH 241/460] Move resource module to a separate crate The resource module does not depend on any other part of MinedMap. --- Cargo.lock | 11 ++++++++++- Cargo.toml | 2 +- crates/resource/Cargo.toml | 11 +++++++++++ {src/resource => crates/resource/src}/biomes.rs | 0 {src/resource => crates/resource/src}/block_color.rs | 0 {src/resource => crates/resource/src}/block_types.rs | 0 .../resource/src}/legacy_block_types.rs | 0 src/resource/mod.rs => crates/resource/src/lib.rs | 0 resource/README.md | 4 ++-- src/main.rs | 2 +- 10 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 crates/resource/Cargo.toml rename {src/resource => crates/resource/src}/biomes.rs (100%) rename {src/resource => crates/resource/src}/block_color.rs (100%) rename {src/resource => crates/resource/src}/block_types.rs (100%) rename {src/resource => crates/resource/src}/legacy_block_types.rs (100%) rename src/resource/mod.rs => crates/resource/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 2b755fb..21eee69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -559,7 +559,6 @@ dependencies = [ "anyhow", "bincode", "clap", - "enumflags2", "fastnbt", "futures-util", "glam", @@ -567,6 +566,7 @@ dependencies = [ "indexmap", "lru", "minedmap-nbt", + "minedmap-resource", "minedmap-types", "num-integer", "num_cpus", @@ -590,6 +590,15 @@ dependencies = [ "serde", ] +[[package]] +name = "minedmap-resource" +version = "0.1.0" +dependencies = [ + "enumflags2", + "glam", + "serde", +] + [[package]] name = "minedmap-types" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7c9ab32..df11d5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ default-run = "minedmap" anyhow = "1.0.68" bincode = "1.3.3" clap = { version = "4.1.4", features = ["derive"] } -enumflags2 = { version = "0.7.5", features = ["serde"] } fastnbt = "2.3.2" futures-util = "0.3.28" glam = "0.24.0" @@ -20,6 +19,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.11.0" minedmap-nbt = { version = "0.1.0", path = "crates/nbt", default-features = false } +minedmap-resource = { version = "0.1.0", path = "crates/resource" } minedmap-types = { version = "0.1.0", 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 new file mode 100644 index 0000000..2436548 --- /dev/null +++ b/crates/resource/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "minedmap-resource" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +enumflags2 = { version = "0.7.7", features = ["serde"] } +glam = "0.24.1" +serde = "1.0.183" diff --git a/src/resource/biomes.rs b/crates/resource/src/biomes.rs similarity index 100% rename from src/resource/biomes.rs rename to crates/resource/src/biomes.rs diff --git a/src/resource/block_color.rs b/crates/resource/src/block_color.rs similarity index 100% rename from src/resource/block_color.rs rename to crates/resource/src/block_color.rs diff --git a/src/resource/block_types.rs b/crates/resource/src/block_types.rs similarity index 100% rename from src/resource/block_types.rs rename to crates/resource/src/block_types.rs diff --git a/src/resource/legacy_block_types.rs b/crates/resource/src/legacy_block_types.rs similarity index 100% rename from src/resource/legacy_block_types.rs rename to crates/resource/src/legacy_block_types.rs diff --git a/src/resource/mod.rs b/crates/resource/src/lib.rs similarity index 100% rename from src/resource/mod.rs rename to crates/resource/src/lib.rs diff --git a/resource/README.md b/resource/README.md index 5211fd3..08857ad 100644 --- a/resource/README.md +++ b/resource/README.md @@ -63,8 +63,8 @@ with MinedMap's resource metadata. 7. Update the source code with the new block colors: ```sh - ./generate.py colors.json ../src/resource/block_types.rs - cargo fmt + ./generate.py colors.json ../crates/resource/src/block_types.rs + cargo fmt --all ``` After the update, the new version should be tested with old savegames (both diff --git a/src/main.rs b/src/main.rs index 9bbe0ab..4409dff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,11 +5,11 @@ mod core; mod io; -mod resource; mod util; mod world; use minedmap_nbt as nbt; +use minedmap_resource as resource; use minedmap_types as types; use anyhow::Result; From 5fc296fc449f595cbdfde112845c6a75981142cc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 17:04:55 +0200 Subject: [PATCH 242/460] Fix binary usage comments --- src/bin/nbtdump.rs | 2 +- src/bin/regiondump.rs | 2 +- src/core/mod.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index a83a199..3b29471 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use anyhow::Result; use clap::Parser; -/// Command line arguments for nbtdump +/// Dump a Minecraft NBT data file in a human-readable format #[derive(Debug, Parser)] struct Args { /// Filename to dump diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index c8e87b4..094cc95 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use anyhow::Result; use clap::Parser; -/// Command line arguments for regiondump +/// Dump a Minecraft NBT region file in a human-readable format #[derive(Debug, Parser)] struct Args { /// Filename to dump diff --git a/src/core/mod.rs b/src/core/mod.rs index a94cf2c..f714223 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -18,7 +18,7 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; -/// Command line arguments for minedmap +/// Generate map tiles from Minecraft save data #[derive(Debug, Parser)] pub struct Args { /// Number of parallel threads to use for processing From 0273e7bc088e0151a4ada0286a3c730100eaa153 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 17:49:37 +0200 Subject: [PATCH 243/460] README.md: update for Rust rewrite --- README.md | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 708fe3d..48053cd 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,16 @@ * 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.19 (no mod installation necessary!) +* Compatible with unmodified Minecraft Java Edition 1.8 up to 1.20 (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 +* 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 * Incremental updates: only recreate map tiles for regions that have changed -* Very low memory usage: typically uses less than 5MB of RAM +* 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](docs/images/MinedMap.png) - ## How to use MinedMap consists of two components: a map renderer generating map tiles from @@ -24,7 +25,7 @@ map, create this empty directory inside the viewer directory. Next, to generate map files run MinedMap passing the source and the destination paths on the command line: ```shell -./MinedMap /path/to/save/game /path/to/viewer/data +minedmap /path/to/save/game /path/to/viewer/data ``` The save game is stored in `saves` inside your Minecraft main directory (`~/.minecraft` on Linux, `C:\Users\\AppData\Roaming\.minecraft` on Windows) @@ -45,27 +46,20 @@ 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. +## Installation -## Building MinedMap - -Precompiled MinedMap binaries for Windows (32bit and 64bit versions) are available under -"Releases" on the Github page. On other platforms, MinedMap must be built from source. - -MinedMap has been tested to work on Windows and Linux. I assume it can also be -built for MacOS and pretty much any POSIX-like system, but I didn't check. ¯\\\_(ツ)\_/¯ - -To build from source, you need Git, CMake, the GCC toolchain and the development -files for the libraries *zlib* and *libpng* (packages *git*, *cmake*, *build-essential*, -*zlib1g-dev* and *libpng-dev* on Debian/Ubuntu). - -Use the following commands to build: +Building the MinedMap map generator requires a recent Rust toolchain. There are no +releases on crates.io or binary releases yet. For now, it can be installed using the +following command: ```shell -git clone https://github.com/NeoRaider/MinedMap.git # Or download a release ZIP and unpack it -mkdir MinedMap-build -cd MinedMap-build -cmake ../MinedMap -DCMAKE_BUILD_TYPE=RELEASE -make +cargo install --git 'https://github.com/NeoRaider/MinedMap.git' ``` -After a successful build, the MinedMap renderer binary can be found in the *src* -subdirectory of the build dir `MinedMap-build`. The viewer is located in the cloned -Git repository `MinedMap`. + +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/NeoRaider/MinedMap/tree/v1.19.1] tag. + From 42a800e08cf03e35ca09c4599c30c8d4d7c84637 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 17:57:59 +0200 Subject: [PATCH 244/460] README.md: fix link syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48053cd..372d31d 100644 --- a/README.md +++ b/README.md @@ -61,5 +61,5 @@ 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/NeoRaider/MinedMap/tree/v1.19.1] tag. +see the [v1.19.1](https://github.com/NeoRaider/MinedMap/tree/v1.19.1) tag. From 003b48951b050afba28789651ac7151e80bfe300 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Aug 2023 19:11:12 +0200 Subject: [PATCH 245/460] world: fix deserialize of unpopulated 1.18+ sections --- src/world/chunk.rs | 51 +++++++++++++++++++++++++++------------------- src/world/de.rs | 28 ++++++++++++++++++------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 53ee165..9285a16 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -112,27 +112,36 @@ impl<'a> Chunk<'a> { let mut section_map = BTreeMap::new(); for section in sections { - section_map.insert( - SectionY(section.y), - ( - SectionV1_13::new( - data_version, - section.block_states.data.as_deref(), - §ion.block_states.palette, - block_types, - ) - .with_context(|| format!("Failed to load section at Y={}", section.y))?, - BiomesV1_18::new( - section.biomes.data.as_deref(), - §ion.biomes.palette, - biome_types, - ) - .with_context(|| format!("Failed to load section biomes at Y={}", section.y))?, - BlockLight::new(section.block_light.as_deref()).with_context(|| { - format!("Failed to load section block light at Y={}", section.y) - })?, - ), - ); + match §ion.section { + de::SectionV1_18Variants::V1_18 { + block_states, + biomes, + block_light, + } => { + 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) + })?, + BlockLight::new(block_light.as_deref()).with_context(|| { + format!("Failed to load section block light at Y={}", section.y) + })?, + ), + ); + } + de::SectionV1_18Variants::Empty {} => {} + }; } Ok(Chunk::V1_18 { section_map }) diff --git a/src/world/de.rs b/src/world/de.rs index cbedf31..5c8f84f 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -28,19 +28,33 @@ pub struct BiomesV1_18 { pub data: Option, } +/// Variable part of a [SectionV1_18] +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum SectionV1_18Variants { + /// Populated 1.18+ section + V1_18 { + /// Block type data + block_states: BlockStatesV1_18, + /// Biome data + biomes: BiomesV1_18, + /// Block light data + #[serde(rename = "BlockLight")] + block_light: Option, + }, + /// Empty section + Empty {}, +} + /// Element of the 1.18+ `sections` list found in a [Chunk] #[derive(Debug, Deserialize)] pub struct SectionV1_18 { /// Y coordinate #[serde(rename = "Y")] pub y: i32, - /// Block type data - pub block_states: BlockStatesV1_18, - /// Biome data - pub biomes: BiomesV1_18, - /// Block light data - #[serde(rename = "BlockLight")] - pub block_light: Option, + /// Variable part of section + #[serde(flatten)] + pub section: SectionV1_18Variants, } /// Version-specific part of a pre-1.18 [Section](SectionV0) From 1616f3b2e2bed619c1d8b1ab26e6f8df5a4d41c8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 13:19:00 +0200 Subject: [PATCH 246/460] Add --version command line argument --- src/bin/nbtdump.rs | 1 + src/bin/regiondump.rs | 1 + src/core/mod.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index 3b29471..66aaa2a 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -10,6 +10,7 @@ use clap::Parser; /// Dump a Minecraft NBT data file in a human-readable format #[derive(Debug, Parser)] +#[command(version)] struct Args { /// Filename to dump file: PathBuf, diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 094cc95..9315022 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -10,6 +10,7 @@ use clap::Parser; /// Dump a Minecraft NBT region file in a human-readable format #[derive(Debug, Parser)] +#[command(version)] struct Args { /// Filename to dump file: PathBuf, diff --git a/src/core/mod.rs b/src/core/mod.rs index f714223..9c000e9 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -20,6 +20,7 @@ use tile_renderer::TileRenderer; /// Generate map tiles from Minecraft save data #[derive(Debug, Parser)] +#[command(version)] pub struct Args { /// Number of parallel threads to use for processing /// From 810a05ab36b75bbc3b481791b89f4fef27028bcf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 13:21:18 +0200 Subject: [PATCH 247/460] Move nbtdump and regiondump commands to examples Do not install the development utilities with minedmap --- {src/bin => examples}/nbtdump.rs | 0 {src/bin => examples}/regiondump.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {src/bin => examples}/nbtdump.rs (100%) rename {src/bin => examples}/regiondump.rs (100%) diff --git a/src/bin/nbtdump.rs b/examples/nbtdump.rs similarity index 100% rename from src/bin/nbtdump.rs rename to examples/nbtdump.rs diff --git a/src/bin/regiondump.rs b/examples/regiondump.rs similarity index 100% rename from src/bin/regiondump.rs rename to examples/regiondump.rs From 2544ee9e80bcd0629a2a411b4b4a9bea93e4aad5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 15:01:48 +0200 Subject: [PATCH 248/460] Move nbtdump and regiondump examples to minedmap-nbt crate --- Cargo.lock | 1 + crates/nbt/Cargo.toml | 3 +++ {examples => crates/nbt/examples}/nbtdump.rs | 0 {examples => crates/nbt/examples}/regiondump.rs | 0 4 files changed, 4 insertions(+) rename {examples => crates/nbt/examples}/nbtdump.rs (100%) rename {examples => crates/nbt/examples}/regiondump.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 21eee69..e97aec3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -584,6 +584,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bytemuck", + "clap", "fastnbt", "flate2", "minedmap-types", diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index ff1d7d2..b144c39 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -15,3 +15,6 @@ serde = "1.0.183" [features] zlib-ng = ["flate2/zlib-ng"] + +[dev-dependencies] +clap = { version = "4.3.23", features = ["derive"] } diff --git a/examples/nbtdump.rs b/crates/nbt/examples/nbtdump.rs similarity index 100% rename from examples/nbtdump.rs rename to crates/nbt/examples/nbtdump.rs diff --git a/examples/regiondump.rs b/crates/nbt/examples/regiondump.rs similarity index 100% rename from examples/regiondump.rs rename to crates/nbt/examples/regiondump.rs From 43dfa6c5447b4b5742a584c4606aef8804791e05 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 15:02:06 +0200 Subject: [PATCH 249/460] Update dependencies --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e97aec3..6c55934 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -815,9 +815,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" dependencies = [ "serde_derive", ] @@ -833,9 +833,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", From 4f3b43e4a44d881b0509f51a2ee60054c3a15b5f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 17:07:03 +0200 Subject: [PATCH 250/460] Add missing serde derive feature to Cargo.toml --- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- crates/types/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index df11d5e..b679609 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" rustc-hash = "1.1.0" -serde = { version = "1.0.152", features = ["rc"] } +serde = { version = "1.0.152", features = ["rc", "derive"] } serde_json = "1.0.99" tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } zstd = "0.12.3" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 2436548..a0ba3ad 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -8,4 +8,4 @@ edition = "2021" [dependencies] enumflags2 = { version = "0.7.7", features = ["serde"] } glam = "0.24.1" -serde = "1.0.183" +serde = { version = "1.0.183", features = ["derive"] } diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index fae230b..50a41fa 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" [dependencies] itertools = "0.11.0" -serde = "1.0.183" +serde = { version = "1.0.183", features = ["derive"] } From 8e369f33fda0d2077e7f65c8d47d483d369af74a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 19:10:54 +0200 Subject: [PATCH 251/460] Add license and repository info to all crates --- Cargo.toml | 10 ++++++++-- crates/nbt/Cargo.toml | 4 +++- crates/resource/Cargo.toml | 4 +++- crates/types/Cargo.toml | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b679609..a536520 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,17 @@ [workspace] members = ["crates/*"] +[workspace.package] +edition = "2021" +license = "MIT" +repository = "https://github.com/NeoRaider/MinedMap" + [package] name = "minedmap" version = "0.1.0" -edition = "2021" -license = "MIT" +edition.workspace = true +license.workspace = true +repository.workspace = true default-run = "minedmap" [dependencies] diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index b144c39..e402a17 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "minedmap-nbt" version = "0.1.0" -edition = "2021" +edition.workspace = true +license.workspace = true +repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index a0ba3ad..3321d28 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "minedmap-resource" version = "0.1.0" -edition = "2021" +edition.workspace = true +license.workspace = true +repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 50a41fa..4830080 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "minedmap-types" version = "0.1.0" -edition = "2021" +edition.workspace = true +license.workspace = true +repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From c010ee9194608385ddf4f0fab54769698aa6ff38 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 21:50:32 +0200 Subject: [PATCH 252/460] Prepare for crates.io release --- Cargo.toml | 2 ++ README.md | 2 +- crates/nbt/Cargo.toml | 4 ++-- crates/nbt/src/lib.rs | 3 +-- crates/resource/Cargo.toml | 4 ++-- crates/resource/src/lib.rs | 4 +++- crates/types/Cargo.toml | 4 ++-- crates/types/src/lib.rs | 3 +-- src/core/mod.rs | 4 ++-- src/main.rs | 3 +-- 10 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a536520..8bd65bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,10 @@ repository = "https://github.com/NeoRaider/MinedMap" [package] name = "minedmap" version = "0.1.0" +description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true +readme.workspace = true repository.workspace = true default-run = "minedmap" diff --git a/README.md b/README.md index 372d31d..3b133fe 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](docs/images/MinedMap.png) +![Screenshot](https://raw.githubusercontent.com/NeoRaider/MinedMap/main/docs/images/MinedMap.png) ## How to use diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml index e402a17..70802ec 100644 --- a/crates/nbt/Cargo.toml +++ b/crates/nbt/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "minedmap-nbt" version = "0.1.0" +description = "MinedMap's handling of Minecraft NBT data and region files" edition.workspace = true license.workspace = true +readme.workspace = true repository.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] anyhow = "1.0.75" bytemuck = "1.13.1" diff --git a/crates/nbt/src/lib.rs b/crates/nbt/src/lib.rs index 0b817b1..98e6d1b 100644 --- a/crates/nbt/src/lib.rs +++ b/crates/nbt/src/lib.rs @@ -1,5 +1,4 @@ -//! MinedMap's of Minecraft NBT data and region files - +#![doc = env!("CARGO_PKG_DESCRIPTION")] #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 3321d28..78917da 100644 --- a/crates/resource/Cargo.toml +++ b/crates/resource/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "minedmap-resource" version = "0.1.0" +description = "Data describing Minecraft biomes and block types" edition.workspace = true license.workspace = true +readme.workspace = true repository.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] enumflags2 = { version = "0.7.7", features = ["serde"] } glam = "0.24.1" diff --git a/crates/resource/src/lib.rs b/crates/resource/src/lib.rs index a0854c5..5423bd7 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -1,4 +1,6 @@ -//! Data describing Minecraft biomes and block types +#![doc = env!("CARGO_PKG_DESCRIPTION")] +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] mod biomes; mod block_color; diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 4830080..4097eea 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "minedmap-types" version = "0.1.0" +description = "Common types used by several MinedMap crates" edition.workspace = true license.workspace = true +readme.workspace = true repository.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] itertools = "0.11.0" serde = { version = "1.0.183", features = ["derive"] } diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 2e4ea61..e219a97 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -1,5 +1,4 @@ -//! Common types used by MinedMap - +#![doc = env!("CARGO_PKG_DESCRIPTION")] #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] diff --git a/src/core/mod.rs b/src/core/mod.rs index 9c000e9..9c775c7 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -18,9 +18,9 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; -/// Generate map tiles from Minecraft save data +/// Command line arguments for minedmap CLI #[derive(Debug, Parser)] -#[command(version)] +#[command(version, about)] pub struct Args { /// Number of parallel threads to use for processing /// diff --git a/src/main.rs b/src/main.rs index 4409dff..31f2889 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ -//! The minedmap generator renders map tile images from Minecraft save data - +#![doc = env!("CARGO_PKG_DESCRIPTION")] #![warn(missing_docs)] #![warn(clippy::missing_docs_in_private_items)] From b0ad1d87657a6dd5a8f475e4ff8adfc41faf8134 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 21:53:22 +0200 Subject: [PATCH 253/460] Cargo.toml: remove redundant default-run --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8bd65bd..403ab49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ edition.workspace = true license.workspace = true readme.workspace = true repository.workspace = true -default-run = "minedmap" [dependencies] anyhow = "1.0.68" From 14e57d2085aacf7402212d2f0034ebdf249cb8e8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 21 Aug 2023 22:01:37 +0200 Subject: [PATCH 254/460] Cargo.toml: add excludes --- Cargo.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 403ab49..0d9ac3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,12 @@ edition.workspace = true license.workspace = true readme.workspace = true repository.workspace = true +exclude = [ + "/.github/", + "/docs/", + "/viewer/", + "/resource/", +] [dependencies] anyhow = "1.0.68" From d39e35508f4265005cc696c1dc3965f4adcd648f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 22 Aug 2023 12:31:40 +0200 Subject: [PATCH 255/460] ci: add Rust CI Check rustfmt/clippy/tests. --- .github/workflows/ci.yml | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9ee03af --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,81 @@ +# A lot of this has been copied from https://github.com/axodotdev/cargo-dist/blob/main/.github/workflows/ci.yml + +name: MinedMap Rust CI + +on: + pull_request: + push: + +env: + RUSTFLAGS: -Dwarnings + RUSTDOCFLAGS: -Dwarnings + +jobs: + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + # Use beta for now for let-else formatting + toolchain: beta + components: rustfmt + - run: cargo fmt --all -- --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy + - uses: swatinem/rust-cache@v2 + - uses: actions-rs/clippy-check@v1 + env: + PWD: ${{ env.GITHUB_WORKSPACE }} + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --workspace --tests --examples + + docs: + runs-on: ubuntu-latest + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rust-docs + - uses: swatinem/rust-cache@v2 + - run: cargo doc --workspace --no-deps --document-private-items + + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + rust: [stable] + steps: + - uses: actions/checkout@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - uses: swatinem/rust-cache@v2 + # Run the tests/doctests (default features) + - run: cargo test --workspace + env: + PWD: ${{ env.GITHUB_WORKSPACE }} + # Run the tests/doctests (no default features) + - run: cargo test --workspace --no-default-features + env: + PWD: ${{ env.GITHUB_WORKSPACE }} + # Test the examples (default features) + - run: cargo test --workspace --examples --bins + env: + PWD: ${{ env.GITHUB_WORKSPACE }} + # Test the examples (no default features) + - run: cargo test --workspace --no-default-features --examples --bins + env: + PWD: ${{ env.GITHUB_WORKSPACE }} From 007c5f72fca6467357db3019dcd53a9ec9b619da Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 25 Aug 2023 21:43:31 +0200 Subject: [PATCH 256/460] Add Code of Conduct Add the Contributor Covenant as a Code of Conduct. --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..7718011 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +mschiffer@universe-factory.net. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. From 4ef020080496c1e011510fc4cf42a73e5ea74895 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 27 Aug 2023 14:27:03 +0200 Subject: [PATCH 257/460] core: display version number based on git-describe --- Cargo.lock | 48 ++++++++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 1 + src/core/mod.rs | 9 ++++++++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c55934..1fcdc89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.29", ] [[package]] @@ -303,7 +303,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.29", ] [[package]] @@ -379,7 +379,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.29", ] [[package]] @@ -408,6 +408,28 @@ version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +[[package]] +name = "git-version" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +dependencies = [ + "git-version-macro", + "proc-macro-hack", +] + +[[package]] +name = "git-version-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "glam" version = "0.24.1" @@ -561,6 +583,7 @@ dependencies = [ "clap", "fastnbt", "futures-util", + "git-version", "glam", "image", "indexmap", @@ -727,6 +750,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.66" @@ -839,7 +868,7 @@ checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.29", ] [[package]] @@ -880,6 +909,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.29" diff --git a/Cargo.toml b/Cargo.toml index 0d9ac3c..5c5cecd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ bincode = "1.3.3" clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" futures-util = "0.3.28" +git-version = "0.3.5" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } diff --git a/src/core/mod.rs b/src/core/mod.rs index 9c775c7..9cc9151 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -11,6 +11,7 @@ use std::path::PathBuf; use anyhow::{Context, Result}; use clap::Parser; +use git_version::git_version; use common::Config; use metadata_writer::MetadataWriter; @@ -18,9 +19,15 @@ use region_processor::RegionProcessor; use tile_mipmapper::TileMipmapper; use tile_renderer::TileRenderer; +/// MinedMap version number +const VERSION: &str = git_version!( + args = ["--abbrev=7", "--match=v*", "--dirty=-modified"], + cargo_prefix = "v", +); + /// Command line arguments for minedmap CLI #[derive(Debug, Parser)] -#[command(version, about)] +#[command(about, version = VERSION.strip_prefix("v").unwrap())] pub struct Args { /// Number of parallel threads to use for processing /// From b5a5c72142d21a383124f53bae221a6e5e0e6042 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 13:18:48 +0200 Subject: [PATCH 258/460] ci: update to actions/checkout@v4 --- .github/workflows/MinedMap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 66edb82..ff6b4a5 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -8,7 +8,7 @@ jobs: steps: - name: 'Checkout' - uses: 'actions/checkout@v3' + uses: 'actions/checkout@v4' - name: 'Get version' id: 'tag' From 7cc6fca7fecd02b68478091d841f12ef23529398 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 15:50:07 +0200 Subject: [PATCH 259/460] ci: merge ci.yml into MinedMap.yml, update actions --- .github/workflows/MinedMap.yml | 58 +++++++++++++++++++++++- .github/workflows/ci.yml | 81 ---------------------------------- 2 files changed, 57 insertions(+), 82 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index ff6b4a5..3f561d0 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -1,9 +1,12 @@ name: 'MinedMap' on: ['push', 'pull_request', 'workflow_dispatch'] +env: + RUSTFLAGS: -Dwarnings + RUSTDOCFLAGS: -Dwarnings + jobs: viewer: - name: 'Package viewer' runs-on: 'ubuntu-20.04' steps: @@ -28,3 +31,56 @@ jobs: with: name: 'MinedMap-${{ steps.tag.outputs.tag }}-viewer' path: 'build/pkg' + + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt + - run: cargo fmt --all -- --check + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy + - uses: swatinem/rust-cache@v2 + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --workspace --tests --examples + + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rust-docs + - uses: swatinem/rust-cache@v2 + - run: cargo doc --workspace --no-deps --document-private-items + + test: + runs-on: ${{ matrix.os }} + strategy: + 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 }} + - uses: swatinem/rust-cache@v2 + - run: cargo test --workspace + - run: cargo test --workspace --no-default-features + - run: cargo test --workspace --examples --bins + - run: cargo test --workspace --no-default-features --examples --bins diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 9ee03af..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,81 +0,0 @@ -# A lot of this has been copied from https://github.com/axodotdev/cargo-dist/blob/main/.github/workflows/ci.yml - -name: MinedMap Rust CI - -on: - pull_request: - push: - -env: - RUSTFLAGS: -Dwarnings - RUSTDOCFLAGS: -Dwarnings - -jobs: - fmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - # Use beta for now for let-else formatting - toolchain: beta - components: rustfmt - - run: cargo fmt --all -- --check - - clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - components: clippy - - uses: swatinem/rust-cache@v2 - - uses: actions-rs/clippy-check@v1 - env: - PWD: ${{ env.GITHUB_WORKSPACE }} - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --workspace --tests --examples - - docs: - runs-on: ubuntu-latest - env: - RUSTDOCFLAGS: -Dwarnings - steps: - - uses: actions/checkout@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - components: rust-docs - - uses: swatinem/rust-cache@v2 - - run: cargo doc --workspace --no-deps --document-private-items - - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - rust: [stable] - steps: - - uses: actions/checkout@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - uses: swatinem/rust-cache@v2 - # Run the tests/doctests (default features) - - run: cargo test --workspace - env: - PWD: ${{ env.GITHUB_WORKSPACE }} - # Run the tests/doctests (no default features) - - run: cargo test --workspace --no-default-features - env: - PWD: ${{ env.GITHUB_WORKSPACE }} - # Test the examples (default features) - - run: cargo test --workspace --examples --bins - env: - PWD: ${{ env.GITHUB_WORKSPACE }} - # Test the examples (no default features) - - run: cargo test --workspace --no-default-features --examples --bins - env: - PWD: ${{ env.GITHUB_WORKSPACE }} From 646534c75598faeeeecdfd31776e454a7e954d4f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 19:08:18 +0200 Subject: [PATCH 260/460] Cargo.toml: add workspace readme key cargo-outdated requires the key to be set to allow inheriting it. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 5c5cecd..4754eb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = ["crates/*"] [workspace.package] edition = "2021" license = "MIT" +readme = "README.md" repository = "https://github.com/NeoRaider/MinedMap" [package] From a153889ce6df138b20920ddc909b7068580805a3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 19:09:18 +0200 Subject: [PATCH 261/460] Update dependencies --- Cargo.lock | 171 ++++++++++++++++++----------------------------------- 1 file changed, 56 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1fcdc89..8913b79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -36,24 +36,23 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -75,9 +74,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys", @@ -97,9 +96,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -125,17 +124,11 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" - [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" @@ -167,20 +160,19 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.3.23" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3" +checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.23" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -190,21 +182,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.36", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "cmake" @@ -287,9 +279,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "enumflags2" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" +checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" dependencies = [ "enumflags2_derive", "serde", @@ -297,13 +289,13 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" +checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.36", ] [[package]] @@ -312,27 +304,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fastnbt" version = "2.4.4" @@ -379,7 +350,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.36", ] [[package]] @@ -404,9 +375,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git-version" @@ -483,17 +454,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] - [[package]] name = "itertools" version = "0.11.0" @@ -520,9 +480,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libz-ng-sys" @@ -534,12 +494,6 @@ dependencies = [ "libc", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" - [[package]] name = "lock_api" version = "0.4.10" @@ -552,18 +506,18 @@ dependencies = [ [[package]] name = "lru" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" dependencies = [ "hashbrown", ] [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" @@ -683,9 +637,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -721,9 +675,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -743,7 +697,7 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "bitflags 1.3.2", + "bitflags", "crc32fast", "fdeflate", "flate2", @@ -758,9 +712,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -802,7 +756,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] @@ -817,19 +771,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustix" -version = "0.38.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" -dependencies = [ - "bitflags 2.4.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - [[package]] name = "ryu" version = "1.0.15" @@ -844,9 +785,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.185" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -862,20 +803,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.185" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.36", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -890,9 +831,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -922,9 +863,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "91e02e55d62894af2a08aca894c6577281f76769ba47c94d5756bec8ac6e7373" dependencies = [ "proc-macro2", "quote", @@ -944,9 +885,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utf8parse" From 63b9f085e1c6ff9b4e334aa26eb68f81149f412f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 18:52:18 +0200 Subject: [PATCH 262/460] ci: add Rust build --- .github/workflows/MinedMap.yml | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 3f561d0..3a6ea3c 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -84,3 +84,57 @@ jobs: - run: cargo test --workspace --no-default-features - run: cargo test --workspace --examples --bins - run: cargo test --workspace --no-default-features --examples --bins + + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: 'macos-11' + target: 'aarch64-apple-darwin' + - os: 'macos-11' + target: 'x86_64-apple-darwin' + - os: 'windows-2019' + target: 'x86_64-pc-windows-msvc' + ext: '.exe' + - os: 'windows-2019' + target: 'i686-pc-windows-msvc' + ext: '.exe' + - os: 'ubuntu-20.04' + target: 'x86_64-unknown-linux-gnu' + + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: 'Checkout' + uses: 'actions/checkout@v4' + + - name: 'Get version' + id: 'tag' + shell: 'bash' + run: | + set -o pipefail + git fetch --prune --unshallow --tags -f + echo "tag=$(git describe --abbrev=7 --match='v*' | sed 's/^v//')" >> $GITHUB_OUTPUT + + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + targets: '${{ matrix.target }}' + + - uses: swatinem/rust-cache@v2 + + - name: 'Build' + shell: 'bash' + run: | + pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' + mkdir -p "$pkgdir" + cargo build --release --target=${{ matrix.target }} + cp target/${{ matrix.target }}/release/minedmap${{ matrix.ext }} "$pkgdir"/ + + - name: 'Archive' + uses: 'actions/upload-artifact@v3' + with: + name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' + path: 'target/pkg' From 92fb2a9ba5f4fdd8ffa2332359c61c86a4ebee77 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 19:54:39 +0200 Subject: [PATCH 263/460] ci: remove unused env GH_TOKEN --- .github/workflows/MinedMap.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 3a6ea3c..98856ca 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -104,8 +104,6 @@ jobs: - os: 'ubuntu-20.04' target: 'x86_64-unknown-linux-gnu' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: 'Checkout' uses: 'actions/checkout@v4' From f898116209a51e005a9722f7a3825452f6731a13 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 20:01:25 +0200 Subject: [PATCH 264/460] ci: add shorter labels for target OS names again --- .github/workflows/MinedMap.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 98856ca..b577b5e 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -92,16 +92,21 @@ jobs: matrix: include: - os: 'macos-11' + label: 'MacOS-Intel' target: 'aarch64-apple-darwin' - os: 'macos-11' + label: 'MacOS-ARM' target: 'x86_64-apple-darwin' - os: 'windows-2019' + label: 'Win64' target: 'x86_64-pc-windows-msvc' ext: '.exe' - os: 'windows-2019' + label: 'Win32' target: 'i686-pc-windows-msvc' ext: '.exe' - os: 'ubuntu-20.04' + label: 'x86_64-unknown-linux-gnu' target: 'x86_64-unknown-linux-gnu' steps: @@ -126,7 +131,7 @@ jobs: - name: 'Build' shell: 'bash' run: | - pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' + pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' mkdir -p "$pkgdir" cargo build --release --target=${{ matrix.target }} cp target/${{ matrix.target }}/release/minedmap${{ matrix.ext }} "$pkgdir"/ @@ -134,5 +139,5 @@ jobs: - name: 'Archive' uses: 'actions/upload-artifact@v3' with: - name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' + name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' path: 'target/pkg' From fcd05b5e1c878c2a5d2b1cae0326336187b7f2cb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 21:45:36 +0200 Subject: [PATCH 265/460] Revert "ci: add shorter labels for target OS names again" This reverts commit f898116209a51e005a9722f7a3825452f6731a13. Let's keep the full target names to stay compatible with cargo-binstall (and possibly cargo-dist in the future). --- .github/workflows/MinedMap.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index b577b5e..98856ca 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -92,21 +92,16 @@ jobs: matrix: include: - os: 'macos-11' - label: 'MacOS-Intel' target: 'aarch64-apple-darwin' - os: 'macos-11' - label: 'MacOS-ARM' target: 'x86_64-apple-darwin' - os: 'windows-2019' - label: 'Win64' target: 'x86_64-pc-windows-msvc' ext: '.exe' - os: 'windows-2019' - label: 'Win32' target: 'i686-pc-windows-msvc' ext: '.exe' - os: 'ubuntu-20.04' - label: 'x86_64-unknown-linux-gnu' target: 'x86_64-unknown-linux-gnu' steps: @@ -131,7 +126,7 @@ jobs: - name: 'Build' shell: 'bash' run: | - pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' + pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' mkdir -p "$pkgdir" cargo build --release --target=${{ matrix.target }} cp target/${{ matrix.target }}/release/minedmap${{ matrix.ext }} "$pkgdir"/ @@ -139,5 +134,5 @@ jobs: - name: 'Archive' uses: 'actions/upload-artifact@v3' with: - name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.label }}' + name: 'MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' path: 'target/pkg' From e57ec81d96133d380fdacb964d5be39dd8ddbe08 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 17 Sep 2023 22:27:24 +0200 Subject: [PATCH 266/460] ci: strip release binaries --- .github/workflows/MinedMap.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/MinedMap.yml b/.github/workflows/MinedMap.yml index 98856ca..b09d620 100644 --- a/.github/workflows/MinedMap.yml +++ b/.github/workflows/MinedMap.yml @@ -125,6 +125,8 @@ jobs: - name: 'Build' shell: 'bash' + env: + RUSTFLAGS: -Dwarnings -Cstrip=symbols run: | pkgdir='target/pkg/MinedMap-${{ steps.tag.outputs.tag }}-${{ matrix.target }}' mkdir -p "$pkgdir" From a8eb2da95d7f075461ac04ba061252eebe992a63 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 19 Sep 2023 23:29:05 +0200 Subject: [PATCH 267/460] Use tracing for configurable logging --- Cargo.lock | 135 +++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/core/mod.rs | 12 ++++ src/core/region_processor.rs | 7 +- src/core/tile_mipmapper.rs | 9 +-- src/core/tile_renderer.rs | 5 +- src/world/section.rs | 5 +- 7 files changed, 164 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8913b79..e6c40e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,6 +478,12 @@ dependencies = [ "libc", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.148" @@ -504,6 +510,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + [[package]] name = "lru" version = "0.11.1" @@ -552,6 +564,8 @@ dependencies = [ "serde", "serde_json", "tokio", + "tracing", + "tracing-subscriber", "zstd", ] @@ -595,6 +609,16 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -650,6 +674,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -823,6 +853,15 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -872,6 +911,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tokio" version = "1.32.0" @@ -883,6 +932,64 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.36", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + [[package]] name = "unicode-ident" version = "1.0.12" @@ -895,12 +1002,40 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[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.48.0" diff --git a/Cargo.toml b/Cargo.toml index 4754eb6..c0fb86f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,8 @@ rustc-hash = "1.1.0" serde = { version = "1.0.152", features = ["rc", "derive"] } serde_json = "1.0.99" tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } +tracing = "0.1.37" +tracing-subscriber = "0.3.17" zstd = "0.12.3" [features] diff --git a/src/core/mod.rs b/src/core/mod.rs index 9cc9151..0e77768 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -35,6 +35,9 @@ pub struct Args { /// use one thread per logical CPU core. #[arg(short, long)] pub jobs: Option, + /// Enable verbose messages + #[arg(short, long)] + pub verbose: bool, /// Minecraft save directory pub input_dir: PathBuf, /// MinedMap data directory @@ -54,6 +57,15 @@ pub fn cli() -> Result<()> { let args = Args::parse(); let config = Config::new(&args); + tracing_subscriber::fmt() + .with_max_level(if args.verbose { + tracing::Level::DEBUG + } else { + tracing::Level::INFO + }) + .with_target(false) + .init(); + setup_threads(config.num_threads)?; let rt = tokio::runtime::Builder::new_current_thread() diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 6e32d94..6fb23c3 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -5,6 +5,7 @@ use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; +use tracing::{debug, error}; use super::common::*; use crate::{ @@ -148,11 +149,11 @@ impl<'a> RegionProcessor<'a> { if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp { - println!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); + debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); return Ok(()); } - println!("Processing region r.{}.{}.mca", coords.x, coords.z); + debug!("Processing region r.{}.{}.mca", coords.x, coords.z); crate::nbt::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { @@ -204,7 +205,7 @@ impl<'a> RegionProcessor<'a> { regions.par_iter().for_each(|&coords| { if let Err(err) = self.process_region(coords) { - eprintln!("Failed to process region {:?}: {:?}", coords, err); + error!("Failed to process region {:?}: {:?}", coords, err); } }); diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index 52fff09..e5d44fd 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -2,6 +2,7 @@ use anyhow::{Context, Result}; use rayon::prelude::*; +use tracing::{debug, warn}; use super::common::*; use crate::{io::fs, types::*}; @@ -83,7 +84,7 @@ impl<'a> TileMipmapper<'a> { let timestamp = match fs::modified_timestamp(&source_path) { Ok(timestamp) => timestamp, Err(err) => { - eprintln!("{}", err); + warn!("{}", err); return None; } }; @@ -96,7 +97,7 @@ impl<'a> TileMipmapper<'a> { }; if Some(input_timestamp) <= output_timestamp { - println!( + debug!( "Skipping unchanged mipmap tile {}", output_path .strip_prefix(&self.config.output_dir) @@ -106,7 +107,7 @@ impl<'a> TileMipmapper<'a> { return Ok(()); } - println!( + debug!( "Rendering mipmap tile {}", output_path .strip_prefix(&self.config.output_dir) @@ -121,7 +122,7 @@ impl<'a> TileMipmapper<'a> { let source = match image::open(&source_path) { Ok(source) => source, Err(err) => { - eprintln!( + warn!( "Failed to read source image {}: {}", source_path.display(), err, diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index c26c559..1386aa9 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -12,6 +12,7 @@ use glam::Vec3; use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; +use tracing::debug; use super::{common::*, region_group::RegionGroup}; use crate::{ @@ -272,7 +273,7 @@ impl<'a> TileRenderer<'a> { let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); if Some(processed_timestamp) <= output_timestamp { - println!( + debug!( "Skipping unchanged tile {}", output_path .strip_prefix(&self.config.output_dir) @@ -282,7 +283,7 @@ impl<'a> TileRenderer<'a> { return Ok(()); } - println!( + debug!( "Rendering tile {}", output_path .strip_prefix(&self.config.output_dir) diff --git a/src/world/section.rs b/src/world/section.rs index 8f47216..998d2f7 100644 --- a/src/world/section.rs +++ b/src/world/section.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; use anyhow::{bail, Context, Result}; use num_integer::div_rem; +use tracing::warn; use super::de; use crate::{ @@ -94,7 +95,7 @@ impl<'a> SectionV1_13<'a> { .map(|entry| { let block_type = block_types.get(&entry.name); if block_type.is_none() { - eprintln!("Unknown block type: {}", entry.name); + warn!("Unknown block type: {}", entry.name); } block_type }) @@ -246,7 +247,7 @@ impl<'a> BiomesV1_18<'a> { .map(|entry| { let biome_type = biome_types.get(entry); if biome_type.is_none() { - eprintln!("Unknown biome type: {}", entry); + warn!("Unknown biome type: {}", entry); } biome_type }) From 7d37f6a5d018ca2e2ba1d67a5a3bc6f1b4716d9a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 20 Sep 2023 00:38:19 +0200 Subject: [PATCH 268/460] Add summary messages --- src/core/region_processor.rs | 38 +++++++++++++++++------ src/core/tile_mipmapper.rs | 60 ++++++++++++++++++++++++++---------- src/core/tile_renderer.rs | 33 +++++++++++++++----- 3 files changed, 97 insertions(+), 34 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 6fb23c3..ac6b42e 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -5,7 +5,7 @@ use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use tracing::{debug, error}; +use tracing::{debug, error, info}; use super::common::*; use crate::{ @@ -132,7 +132,7 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single region file - fn process_region(&self, coords: TileCoords) -> Result<()> { + fn process_region(&self, coords: TileCoords) -> Result { /// Width/height of the region data const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; @@ -150,7 +150,7 @@ impl<'a> RegionProcessor<'a> { if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp { debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); - return Ok(()); + return Ok(false); } debug!("Processing region r.{}.{}.mca", coords.x, coords.z); @@ -188,7 +188,7 @@ impl<'a> RegionProcessor<'a> { Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; } - Ok(()) + Ok(true) } /// Iterates over all region files of a Minecraft save directory @@ -203,11 +203,31 @@ impl<'a> RegionProcessor<'a> { fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; - regions.par_iter().for_each(|&coords| { - if let Err(err) = self.process_region(coords) { - error!("Failed to process region {:?}: {:?}", coords, err); - } - }); + info!("Processing region files..."); + + let mut results = vec![]; + regions + .par_iter() + .map(|&coords| { + let result = self.process_region(coords); + if let Err(err) = &result { + error!("Failed to process region {:?}: {:?}", coords, err); + } + result + }) + .collect_into_vec(&mut results); + + let processed = results + .iter() + .filter(|result| matches!(result, Ok(true))) + .count(); + let errors = results.iter().filter(|result| result.is_err()).count(); + info!( + "Processed region files ({} processed, {} unchanged, {} errors)", + processed, + results.len() - processed, + errors, + ); Ok(regions) } diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index e5d44fd..d2b1ac5 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use rayon::prelude::*; -use tracing::{debug, warn}; +use tracing::{debug, info, warn}; use super::common::*; use crate::{io::fs, types::*}; @@ -58,7 +58,7 @@ impl<'a> TileMipmapper<'a> { level: usize, coords: TileCoords, prev: &TileCoordMap, - ) -> Result<()> + ) -> Result<(bool, bool)> where [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, @@ -93,7 +93,7 @@ impl<'a> TileMipmapper<'a> { .collect(); let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { - return Ok(()); + return Ok((false, false)); }; if Some(input_timestamp) <= output_timestamp { @@ -104,7 +104,7 @@ impl<'a> TileMipmapper<'a> { .expect("tile path must be in output directory") .display(), ); - return Ok(()); + return Ok((true, false)); } debug!( @@ -143,7 +143,9 @@ impl<'a> TileMipmapper<'a> { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") - }) + })?; + + Ok((true, true)) } /// Runs the mipmap generation @@ -165,24 +167,48 @@ impl<'a> TileMipmapper<'a> { 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); - next.0.par_iter().try_for_each(|(&z, xs)| { - xs.par_iter().try_for_each(|&x| { - let coords = TileCoords { x, z }; - self.render_mipmap::>(TileKind::Map, level, coords, prev)?; - self.render_mipmap::>( - TileKind::Lightmap, - level, - coords, - prev, - )?; - anyhow::Ok(()) + let (total, processed) = next + .0 + .par_iter() + .flat_map(|(&z, xs)| { + let mipmapper = &self; + xs.par_iter().map(move |&x| { + let coords = TileCoords { x, z }; + let (found_map, processed_map) = mipmapper + .render_mipmap::>(TileKind::Map, level, coords, prev)?; + let (found_light, processed_light) = mipmapper + .render_mipmap::>( + TileKind::Lightmap, + level, + coords, + prev, + )?; + anyhow::Ok(( + usize::from(found_map) + usize::from(found_light), + usize::from(processed_map) + usize::from(processed_light), + )) + }) }) - })?; + .try_reduce( + || (0, 0), + |(found_a, processed_a), (found_b, processed_b)| { + Ok((found_a + found_b, processed_a + processed_b)) + }, + )?; + + info!( + "Generated level {} mipmaps ({} processed, {} unchanged)", + level, + processed, + total - processed, + ); tile_stack.push(next); } diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 1386aa9..219e7c8 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -12,7 +12,7 @@ use glam::Vec3; use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; -use tracing::debug; +use tracing::{debug, info}; use super::{common::*, region_group::RegionGroup}; use crate::{ @@ -263,7 +263,7 @@ impl<'a> TileRenderer<'a> { } /// Renders and saves a region tile image - fn render_tile(&self, coords: TileCoords) -> Result<()> { + fn render_tile(&self, coords: TileCoords) -> Result { /// Width/height of a tile image const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; @@ -280,7 +280,7 @@ impl<'a> TileRenderer<'a> { .expect("tile path must be in output directory") .display(), ); - return Ok(()); + return Ok(false); } debug!( @@ -307,18 +307,35 @@ impl<'a> TileRenderer<'a> { .write_to(file, image::ImageFormat::Png) .context("Failed to save image") }, - ) + )?; + + Ok(true) } /// Runs the tile generation pub fn run(self) -> Result<()> { fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; + info!("Rendering map tiles..."); + // Use par_bridge to process items in order (for better use of region cache) - self.regions.iter().par_bridge().try_for_each(|&coords| { - self.render_tile(coords) - .with_context(|| format!("Failed to render tile {:?}", coords)) - })?; + let processed = self + .regions + .iter() + .par_bridge() + .map(|&coords| { + anyhow::Ok(usize::from( + self.render_tile(coords) + .with_context(|| format!("Failed to render tile {:?}", coords))?, + )) + }) + .try_reduce(|| 0, |a, b| Ok(a + b))?; + + info!( + "Rendered map tiles ({} processed, {} unchanged)", + processed, + self.regions.len() - processed, + ); Ok(()) } From c7145c5c4ae4118f54734c1345c8eec1cd32fd14 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Sep 2023 17:47:11 +0200 Subject: [PATCH 269/460] Cargo.toml: add cargo-release config --- Cargo.toml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c0fb86f..1f37f42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ license = "MIT" readme = "README.md" repository = "https://github.com/NeoRaider/MinedMap" +[workspace.metadata.release] +consolidate-commits = false + [package] name = "minedmap" version = "0.1.0" @@ -22,6 +25,17 @@ exclude = [ "/resource/", ] +[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}}"}, + {file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1}, + {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}"}, + {file="CHANGELOG.md", search="", replace="\n\n## [Unreleased] - ReleaseDate", exactly=1}, + {file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/neocturne/MinedMap/compare/{{tag_name}}...HEAD", exactly=1}, +] + [dependencies] anyhow = "1.0.68" bincode = "1.3.3" From 8873ff74c4599a1dc9afcf86fc6434790c0917ff Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Sep 2023 10:08:58 +0200 Subject: [PATCH 270/460] Update dependencies --- Cargo.lock | 82 +++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6c40e4..ec8779a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,9 +36,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -50,15 +50,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys", @@ -160,9 +160,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.3" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", @@ -189,7 +189,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.36", + "syn 2.0.37", ] [[package]] @@ -228,16 +228,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -295,7 +285,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.36", + "syn 2.0.37", ] [[package]] @@ -350,7 +340,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.36", + "syn 2.0.37", ] [[package]] @@ -403,15 +393,15 @@ dependencies = [ [[package]] name = "glam" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226" +checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ "ahash", "allocator-api2", @@ -425,9 +415,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "image" @@ -445,9 +435,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown", @@ -760,9 +750,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -770,14 +760,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -839,7 +827,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.36", + "syn 2.0.37", ] [[package]] @@ -855,9 +843,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b" dependencies = [ "lazy_static", ] @@ -879,9 +867,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "strsim" @@ -902,9 +890,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.36" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e02e55d62894af2a08aca894c6577281f76769ba47c94d5756bec8ac6e7373" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -952,7 +940,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.36", + "syn 2.0.37", ] [[package]] From d9d7cda5eeee6e989a2acc6696ca153b4543b726 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Sep 2023 10:08:49 +0200 Subject: [PATCH 271/460] Add CHANGELOG.md --- CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9f500f1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ + + +## [Unreleased] - ReleaseDate + +This is a complete rewrite of the map renderer in Rust, as the previous C++ +implementation was getting more and more difficult to maintain and keep current +versions of Minecraft supported. + +The new implementation is generally faster than the old one (by using better +data structures), but it also uses a bit more RAM and storage space for +intermediate data. + +### Added + +- Added support for Minecraft 1.20 biomes and block types +- Multithreading: Pass `-j N` to minedmap to use *N* CPU cores in parallel. Note + that this also multiplies the RAM requirements of MinedMap. +- Extended OS support: MinedMap should now run on every system supported by Rust + as a target. As I don't have a way to test these builds, binary releases are + still limited to Windows and Linux for now; on other targets, MinedMap must + be built from source. + +### Changed + +- Biome smoothing uses a different filter kernel now, which might result in + nicer gradients? +- Log messages have been reduced. Pass `-v` to get a message for each + processed file again. +- The intermediate data directory `biome` in the output directory has been + replaced with a new `processed` directory. The `biome` directory can be + deleted when reusing the output directory of an older MinedMap version. + +### Fixed + +- Warnings about unknown biomes or block types have been reduced to once per + chunk/section, so rending is not slowed down by these message so much anymore. + + Full support for custom biomes datapacks might be added in a future release. + + +[Unreleased]: https://github.com/NeoRaider/MinedMap/compare/v1.19.1...HEAD From 1559486727ff8b27ebacf1ff7c736b67e2c0be3c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Sep 2023 16:17:49 +0200 Subject: [PATCH 272/460] README.md: update for release --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3b133fe..4dcd106 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,8 @@ the generated map files to public webspace to make the map available to others. ## Installation -Building the MinedMap map generator requires a recent Rust toolchain. There are no -releases on crates.io or binary releases yet. For now, it can be installed using the -following command: +Building the MinedMap map generator requires a recent Rust toolchain. The +following command can be used to build the current development version from source: ```shell cargo install --git 'https://github.com/NeoRaider/MinedMap.git' ``` From ceb71f035caa5214e19dda49c63b6ea4b36c200b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Sep 2023 16:53:07 +0200 Subject: [PATCH 273/460] minedmap 2.0.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 9f500f1..5cafcf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.0.0] - 2023-09-30 + This is a complete rewrite of the map renderer in Rust, as the previous C++ implementation was getting more and more difficult to maintain and keep current versions of Minecraft supported. @@ -38,4 +40,5 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/NeoRaider/MinedMap/compare/v1.19.1...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.0.0...HEAD +[2.0.0]: https://github.com/NeoRaider/MinedMap/compare/v1.19.1...v2.0.0 diff --git a/Cargo.lock b/Cargo.lock index ec8779a..4687cf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -532,7 +532,7 @@ dependencies = [ [[package]] name = "minedmap" -version = "0.1.0" +version = "2.0.0" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index 1f37f42..fcef957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ consolidate-commits = false [package] name = "minedmap" -version = "0.1.0" +version = "2.0.0" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From 30e5aee09e1e3387ae7c652039946832410021d9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 18:27:49 +0200 Subject: [PATCH 274/460] Update dependencies --- Cargo.lock | 64 ++++++++++++++++++++++++++---------------------------- Cargo.toml | 4 ++-- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4687cf0..5cdfec3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,9 +132,9 @@ checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" @@ -189,7 +189,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -285,7 +285,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -340,7 +340,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -461,9 +461,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] @@ -476,9 +476,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libz-ng-sys" @@ -508,18 +508,18 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" dependencies = [ "hashbrown", ] [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -632,9 +632,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -732,9 +732,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -827,7 +827,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -843,9 +843,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -890,9 +890,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -911,9 +911,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "parking_lot", @@ -940,7 +940,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1092,30 +1092,28 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "zstd" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "6.0.6" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" dependencies = [ - "libc", "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index fcef957..f9b1f0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ git-version = "0.3.5" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } -lru = "0.11.0" +lru = "0.12.0" minedmap-nbt = { version = "0.1.0", path = "crates/nbt", default-features = false } minedmap-resource = { version = "0.1.0", path = "crates/resource" } minedmap-types = { version = "0.1.0", path = "crates/types" } @@ -59,7 +59,7 @@ serde_json = "1.0.99" tokio = { version = "1.31.0", features = ["rt", "parking_lot", "sync"] } tracing = "0.1.37" tracing-subscriber = "0.3.17" -zstd = "0.12.3" +zstd = "0.13.0" [features] default = ["zlib-ng"] From 920547f64a57648aabef0b298ebc0ea3ada1bc2b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:14:13 +0200 Subject: [PATCH 275/460] core/tile_mipmapper: use mpsc channels for counters Make the code a bit easier to understand. --- src/core/tile_mipmapper.rs | 73 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index d2b1ac5..cc1a8d4 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -1,5 +1,7 @@ //! The [TileMipmapper] +use std::sync::mpsc; + use anyhow::{Context, Result}; use rayon::prelude::*; use tracing::{debug, info, warn}; @@ -58,7 +60,9 @@ impl<'a> TileMipmapper<'a> { level: usize, coords: TileCoords, prev: &TileCoordMap, - ) -> Result<(bool, bool)> + count_total: &mpsc::Sender<()>, + count_processed: &mpsc::Sender<()>, + ) -> Result<()> where [P::Subpixel]: image::EncodableLayout, image::ImageBuffer>: Into, @@ -93,9 +97,11 @@ impl<'a> TileMipmapper<'a> { .collect(); let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { - return Ok((false, false)); + return Ok(()); }; + count_total.send(()).unwrap(); + if Some(input_timestamp) <= output_timestamp { debug!( "Skipping unchanged mipmap tile {}", @@ -104,7 +110,7 @@ impl<'a> TileMipmapper<'a> { .expect("tile path must be in output directory") .display(), ); - return Ok((true, false)); + return Ok(()); } debug!( @@ -145,7 +151,8 @@ impl<'a> TileMipmapper<'a> { .context("Failed to save image") })?; - Ok((true, true)) + count_processed.send(()).unwrap(); + Ok(()) } /// Runs the mipmap generation @@ -174,34 +181,38 @@ impl<'a> TileMipmapper<'a> { let next = Self::map_coords(prev); - let (total, processed) = next - .0 + let (total_send, total_recv) = mpsc::channel(); + let (processed_send, processed_recv) = mpsc::channel(); + + next.0 .par_iter() - .flat_map(|(&z, xs)| { - let mipmapper = &self; - xs.par_iter().map(move |&x| { - let coords = TileCoords { x, z }; - let (found_map, processed_map) = mipmapper - .render_mipmap::>(TileKind::Map, level, coords, prev)?; - let (found_light, processed_light) = mipmapper - .render_mipmap::>( - TileKind::Lightmap, - level, - coords, - prev, - )?; - anyhow::Ok(( - usize::from(found_map) + usize::from(found_light), - usize::from(processed_map) + usize::from(processed_light), - )) - }) - }) - .try_reduce( - || (0, 0), - |(found_a, processed_a), (found_b, processed_b)| { - Ok((found_a + found_b, processed_a + processed_b)) - }, - )?; + .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)", From 38da1616d5af2edf4c16e204073a93bbd0d3ba73 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 18:30:28 +0200 Subject: [PATCH 276/460] core/region_processor: rename path to input_path in process_region() Make the variable names more consistent. --- src/core/region_processor.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index ac6b42e..55f7227 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -139,8 +139,8 @@ impl<'a> RegionProcessor<'a> { let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); - let path = self.config.region_path(coords); - let input_timestamp = fs::modified_timestamp(&path)?; + let input_path = self.config.region_path(coords); + let input_timestamp = fs::modified_timestamp(&input_path)?; let output_path = self.config.processed_path(coords); let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); @@ -155,7 +155,7 @@ impl<'a> RegionProcessor<'a> { debug!("Processing region r.{}.{}.mca", coords.x, coords.z); - crate::nbt::region::from_file(path)?.foreach_chunk( + crate::nbt::region::from_file(input_path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData { blocks, From 46c04e632fb2e0e545cb1f8f47e21c5a7f7e8f44 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:31:02 +0200 Subject: [PATCH 277/460] core/region_processor: temporarily disable stat output --- src/core/region_processor.rs | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 55f7227..6e5adbe 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -205,29 +205,19 @@ impl<'a> RegionProcessor<'a> { info!("Processing region files..."); - let mut results = vec![]; - regions - .par_iter() - .map(|&coords| { - let result = self.process_region(coords); - if let Err(err) = &result { - error!("Failed to process region {:?}: {:?}", coords, err); - } - result - }) - .collect_into_vec(&mut results); + regions.par_iter().for_each(|&coords| { + let result = self.process_region(coords); + if let Err(err) = &result { + error!("Failed to process region {:?}: {:?}", coords, err); + } + }); - let processed = results - .iter() - .filter(|result| matches!(result, Ok(true))) - .count(); - let errors = results.iter().filter(|result| result.is_err()).count(); - info!( - "Processed region files ({} processed, {} unchanged, {} errors)", - processed, - results.len() - processed, - errors, - ); + // info!( + // "Processed region files ({} processed, {} unchanged, {} errors)", + // processed, + // results.len() - processed, + // errors, + // ); Ok(regions) } From 284892cea6a15cc16b68557a99d3c1f519d10abe Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:36:18 +0200 Subject: [PATCH 278/460] core/region_processor: make all process_region() error fatal Less severe errors will be changed not to be passed up to run(). --- src/core/region_processor.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 6e5adbe..db25fc2 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -5,7 +5,7 @@ use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use tracing::{debug, error, info}; +use tracing::{debug, info}; use super::common::*; use crate::{ @@ -205,12 +205,12 @@ impl<'a> RegionProcessor<'a> { info!("Processing region files..."); - regions.par_iter().for_each(|&coords| { - let result = self.process_region(coords); - if let Err(err) = &result { - error!("Failed to process region {:?}: {:?}", coords, err); - } - }); + regions.par_iter().try_for_each(|&coords| { + let _ = self + .process_region(coords) + .with_context(|| format!("Failed to process region {:?}", coords))?; + anyhow::Ok(()) + })?; // info!( // "Processed region files ({} processed, {} unchanged, {} errors)", From 09374d755e25a5dec400177ab7a58f40424e40c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:44:14 +0200 Subject: [PATCH 279/460] core/region_processor: introduce RegionProcessorStatus enum --- src/core/region_processor.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index db25fc2..fff0b25 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -31,6 +31,19 @@ fn parse_region_filename(file_name: &OsStr) -> Option { }) } +/// [RegionProcessor::process_region] return values +#[derive(Debug, Clone, Copy)] +enum RegionProcessorStatus { + /// Region was processed + Ok, + /// Region was unchanged and skipped + Skipped, + /// Reading the region failed, previous processed data is reused + ErrorOk, + /// Reading the region failed, no previous data available + ErrorMissing, +} + /// Type with methods for processing the regions of a Minecraft save directory /// /// The RegionProcessor builds lightmap tiles as well as processed region data @@ -132,7 +145,7 @@ impl<'a> RegionProcessor<'a> { } /// Processes a single region file - fn process_region(&self, coords: TileCoords) -> Result { + fn process_region(&self, coords: TileCoords) -> Result { /// Width/height of the region data const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; @@ -150,7 +163,7 @@ impl<'a> RegionProcessor<'a> { if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp { debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); - return Ok(false); + return Ok(RegionProcessorStatus::Skipped); } debug!("Processing region r.{}.{}.mca", coords.x, coords.z); @@ -188,7 +201,7 @@ impl<'a> RegionProcessor<'a> { Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; } - Ok(true) + Ok(RegionProcessorStatus::Ok) } /// Iterates over all region files of a Minecraft save directory From fd48f94f16b1028227bd26bee82d1597ae311352 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:49:26 +0200 Subject: [PATCH 280/460] core/region_processor: make regular processing errors non-fatal again Never fail because of invalid save files. --- src/core/region_processor.rs | 64 ++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index fff0b25..c1193b6 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -5,7 +5,7 @@ use std::{ffi::OsStr, path::Path, time::SystemTime}; use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use tracing::{debug, info}; +use tracing::{debug, info, warn}; use super::common::*; use crate::{ @@ -168,31 +168,47 @@ impl<'a> RegionProcessor<'a> { debug!("Processing region r.{}.{}.mca", coords.x, coords.z); - crate::nbt::region::from_file(input_path)?.foreach_chunk( - |chunk_coords, data: world::de::Chunk| { - let Some(layer::LayerData { - blocks, - biomes, - block_light, - depths, - }) = self - .process_chunk(&mut processed_region.biome_list, data) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? - else { - return Ok(()); - }; - processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { - blocks, - biomes, - depths, - })); + if let Err(err) = (|| -> Result<()> { + crate::nbt::region::from_file(input_path)?.foreach_chunk( + |chunk_coords, data: world::de::Chunk| { + let Some(layer::LayerData { + blocks, + biomes, + block_light, + depths, + }) = self + .process_chunk(&mut processed_region.biome_list, data) + .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? + else { + return Ok(()); + }; + processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + blocks, + biomes, + depths, + })); - let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); + let chunk_lightmap = Self::render_chunk_lightmap(block_light); + overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); - Ok(()) - }, - )?; + Ok(()) + }, + ) + })() { + if output_timestamp.is_some() && lightmap_timestamp.is_some() { + warn!( + "Failed to process region {:?}, using old data: {:?}", + coords, err + ); + return Ok(RegionProcessorStatus::ErrorOk); + } else { + warn!( + "Failed to process region {:?}, no old data available: {:?}", + coords, err + ); + return Ok(RegionProcessorStatus::ErrorMissing); + } + } if Some(input_timestamp) > output_timestamp { Self::save_region(&output_path, &processed_region, input_timestamp)?; From 506631a18f9e20875e7bde703700851b61e15b24 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 19:59:14 +0200 Subject: [PATCH 281/460] core/region_processor: only return available regions Ignore regions that failed to process and have no old processed data. --- src/core/region_processor.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index c1193b6..caaf8ec 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, path::Path, time::SystemTime}; +use std::{ffi::OsStr, path::Path, sync::mpsc, time::SystemTime}; use anyhow::{Context, Result}; use indexmap::IndexSet; @@ -32,7 +32,7 @@ fn parse_region_filename(file_name: &OsStr) -> Option { } /// [RegionProcessor::process_region] return values -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] enum RegionProcessorStatus { /// Region was processed Ok, @@ -224,23 +224,28 @@ impl<'a> RegionProcessor<'a> { /// /// Returns a list of the coordinates of all processed regions pub fn run(self) -> Result> { - let mut regions = self.collect_regions()?; - - // 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 })); - fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; info!("Processing region files..."); - regions.par_iter().try_for_each(|&coords| { - let _ = self + let (region_send, region_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 { + region_send.send(coords).unwrap(); + } + anyhow::Ok(()) })?; + drop(region_send); + let mut regions: Vec<_> = region_recv.into_iter().collect(); + // info!( // "Processed region files ({} processed, {} unchanged, {} errors)", // processed, @@ -248,6 +253,9 @@ impl<'a> RegionProcessor<'a> { // errors, // ); + // 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 })); + Ok(regions) } } From fba9b6cb553c2760d7399abca196f858f572f6a7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 12 Oct 2023 20:08:02 +0200 Subject: [PATCH 282/460] core/region_processor: reenable stat output --- src/core/region_processor.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index caaf8ec..6442da0 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -230,6 +230,8 @@ 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(); self.collect_regions()?.par_iter().try_for_each(|&coords| { let ret = self @@ -240,18 +242,31 @@ impl<'a> RegionProcessor<'a> { region_send.send(coords).unwrap(); } + match ret { + RegionProcessorStatus::Ok => processed_send.send(()).unwrap(), + RegionProcessorStatus::Skipped => {} + RegionProcessorStatus::ErrorOk | RegionProcessorStatus::ErrorMissing => { + error_send.send(()).unwrap() + } + } + anyhow::Ok(()) })?; drop(region_send); let mut regions: Vec<_> = region_recv.into_iter().collect(); - // info!( - // "Processed region files ({} processed, {} unchanged, {} errors)", - // processed, - // results.len() - processed, - // errors, - // ); + drop(processed_send); + let processed = processed_recv.into_iter().count(); + drop(error_send); + let errors = error_recv.into_iter().count(); + + info!( + "Processed region files ({} processed, {} unchanged, {} errors)", + processed, + regions.len() - processed - errors, + errors, + ); // 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 })); From 2c1c8c17ef7a7b156d8f4813289a8f5c0c5f515c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 18:49:25 +0100 Subject: [PATCH 283/460] Update dependencies --- Cargo.lock | 179 ++++++++++++++++++++-------------------- crates/types/Cargo.toml | 2 +- 2 files changed, 91 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cdfec3..fc57421 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,13 +19,14 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -160,9 +161,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.6" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" dependencies = [ "clap_builder", "clap_derive", @@ -170,9 +171,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" dependencies = [ "anstream", "anstyle", @@ -182,21 +183,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cmake" @@ -285,7 +286,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -308,18 +309,18 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" dependencies = [ "simd-adler32", ] [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "libz-ng-sys", @@ -328,32 +329,32 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-core", "futures-macro", @@ -371,24 +372,22 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git-version" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +checksum = "13ad01ffa8221f7fe8b936d6ffb2a3e7ad428885a04fad51866a5f33eafda57c" dependencies = [ "git-version-macro", - "proc-macro-hack", ] [[package]] name = "git-version-macro" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +checksum = "84488ccbdb24ad6f56dc1863b4a8154a7856cd3c6c7610401634fab3cb588dae" dependencies = [ - "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -399,9 +398,9 @@ checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ "ahash", "allocator-api2", @@ -435,9 +434,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", @@ -446,9 +445,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" dependencies = [ "either", ] @@ -476,9 +475,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libz-ng-sys" @@ -492,9 +491,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -682,9 +681,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", @@ -724,12 +723,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.69" @@ -770,9 +763,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] @@ -803,9 +796,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] @@ -821,20 +814,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -867,9 +860,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "strsim" @@ -879,20 +872,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -911,9 +893,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "parking_lot", @@ -922,11 +904,10 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -934,20 +915,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -955,20 +936,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -1090,6 +1071,26 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zstd" version = "0.13.0" diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 4097eea..3e8f63d 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -8,5 +8,5 @@ readme.workspace = true repository.workspace = true [dependencies] -itertools = "0.11.0" +itertools = "0.12.0" serde = { version = "1.0.183", features = ["derive"] } From 412568603e1c4b11dced9a2859f51152954fcd23 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 18:51:11 +0100 Subject: [PATCH 284/460] README.md: minor updates --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4dcd106..75877b4 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ 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 based on [Leaflet](https://leafletjs.com/). The map renderer is heavily inspired by -[MapRend](https://github.com/YSelfTool/MapRend), but it has been implemented in C++ -from scratch for highest performance. +[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 @@ -48,8 +48,8 @@ the generated map files to public webspace to make the map available to others. ## Installation -Building the MinedMap map generator requires a recent Rust toolchain. The -following command can be used to build the current development version from source: +Building the MinedMap map generator from source requires a recent Rust toolchain. The +following command can be used to build the current development version: ```shell cargo install --git 'https://github.com/NeoRaider/MinedMap.git' ``` From 5f2dea6b4fac8d869057aac0dc9bbdb1721f433c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 18:58:53 +0100 Subject: [PATCH 285/460] minedmap-types 0.1.1 --- crates/types/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 3e8f63d..41e36cf 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minedmap-types" -version = "0.1.0" +version = "0.1.1" description = "Common types used by several MinedMap crates" edition.workspace = true license.workspace = true From cc9d2c00b4d8cab4339b834d2cb539a50de4809e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 19:01:15 +0100 Subject: [PATCH 286/460] Cargo.lock: update --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index fc57421..924b580 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,7 +582,7 @@ dependencies = [ [[package]] name = "minedmap-types" -version = "0.1.0" +version = "0.1.1" dependencies = [ "itertools", "serde", From ec4b1053c5c55c8a4c125ff1ec4424150cb72daf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 19:04:39 +0100 Subject: [PATCH 287/460] CHANGELOG.md: update for invalid region handling fix --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cafcf2..e1e6c27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## [Unreleased] - ReleaseDate +### Fixed + +- Proceed with missing tiles rather can failing completely when an invalid + region file is encountered and no processed data from a previous run exists + ## [2.0.0] - 2023-09-30 This is a complete rewrite of the map renderer in Rust, as the previous C++ From 196e21718fcbed7b0609664eb701788e78d44e75 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 19:06:25 +0100 Subject: [PATCH 288/460] minedmap 2.0.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 e1e6c27..c638d6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - ReleaseDate +## [2.0.1] - 2023-11-18 + ### Fixed - Proceed with missing tiles rather can failing completely when an invalid @@ -45,5 +47,6 @@ intermediate data. Full support for custom biomes datapacks might be added in a future release. -[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.0.0...HEAD +[Unreleased]: https://github.com/neocturne/MinedMap/compare/v2.0.1...HEAD +[2.0.1]: https://github.com/neocturne/MinedMap/compare/v2.0.0...v2.0.1 [2.0.0]: https://github.com/NeoRaider/MinedMap/compare/v1.19.1...v2.0.0 diff --git a/Cargo.lock b/Cargo.lock index 924b580..95ee246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "minedmap" -version = "2.0.0" +version = "2.0.1" dependencies = [ "anyhow", "bincode", diff --git a/Cargo.toml b/Cargo.toml index f9b1f0b..468f0f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ consolidate-commits = false [package] name = "minedmap" -version = "2.0.0" +version = "2.0.1" description = "Generate browsable maps from Minecraft save data" edition.workspace = true license.workspace = true From b32bdb4d8e6a0588a467c92ef08d7161c9ca0fca Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 18 Nov 2023 21:15:04 +0100 Subject: [PATCH 289/460] README.md: mention minimum supported Rust version --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75877b4..9a8755e 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,8 @@ 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. The -following command can be used to build the current development version: +Building the MinedMap map 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/NeoRaider/MinedMap.git' ``` From 74a4fc93d011f30ab4bbd7974c669908128a4c83 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 19:01:36 +0100 Subject: [PATCH 290/460] world/de: rename Variants enums to Variant --- src/world/chunk.rs | 14 +++++++------- src/world/de.rs | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/world/chunk.rs b/src/world/chunk.rs index 9285a16..77a543c 100644 --- a/src/world/chunk.rs +++ b/src/world/chunk.rs @@ -93,10 +93,10 @@ impl<'a> Chunk<'a> { let data_version = data.data_version.unwrap_or_default(); match &data.chunk { - de::ChunkVariants::V1_18 { sections } => { + de::ChunkVariant::V1_18 { sections } => { Self::new_v1_18(data_version, sections, block_types, biome_types) } - de::ChunkVariants::V0 { level } => { + de::ChunkVariant::V0 { level } => { Self::new_v0(data_version, level, block_types, biome_types) } } @@ -113,7 +113,7 @@ impl<'a> Chunk<'a> { for section in sections { match §ion.section { - de::SectionV1_18Variants::V1_18 { + de::SectionV1_18Variant::V1_18 { block_states, biomes, block_light, @@ -140,7 +140,7 @@ impl<'a> Chunk<'a> { ), ); } - de::SectionV1_18Variants::Empty {} => {} + de::SectionV1_18Variant::Empty {} => {} }; } @@ -163,7 +163,7 @@ impl<'a> Chunk<'a> { format!("Failed to load section block light at Y={}", section.y) })?; match §ion.section { - de::SectionV0Variants::V1_13 { + de::SectionV0Variant::V1_13 { block_states, palette, } => { @@ -183,7 +183,7 @@ impl<'a> Chunk<'a> { ), ); } - de::SectionV0Variants::V0 { blocks, data } => { + de::SectionV0Variant::V0 { blocks, data } => { section_map_v0.insert( SectionY(section.y.into()), ( @@ -194,7 +194,7 @@ impl<'a> Chunk<'a> { ), ); } - de::SectionV0Variants::Empty {} => {} + de::SectionV0Variant::Empty {} => {} } } diff --git a/src/world/de.rs b/src/world/de.rs index 5c8f84f..cf1b6b5 100644 --- a/src/world/de.rs +++ b/src/world/de.rs @@ -31,7 +31,7 @@ pub struct BiomesV1_18 { /// Variable part of a [SectionV1_18] #[derive(Debug, Deserialize)] #[serde(untagged)] -pub enum SectionV1_18Variants { +pub enum SectionV1_18Variant { /// Populated 1.18+ section V1_18 { /// Block type data @@ -54,13 +54,13 @@ pub struct SectionV1_18 { pub y: i32, /// Variable part of section #[serde(flatten)] - pub section: SectionV1_18Variants, + pub section: SectionV1_18Variant, } /// Version-specific part of a pre-1.18 [Section](SectionV0) #[derive(Debug, Deserialize)] #[serde(untagged)] -pub enum SectionV0Variants { +pub enum SectionV0Variant { /// v1.13+ data #[serde(rename_all = "PascalCase")] V1_13 { @@ -91,7 +91,7 @@ pub struct SectionV0 { pub block_light: Option, /// Version-specific data #[serde(flatten)] - pub section: SectionV0Variants, + pub section: SectionV0Variant, } /// Pre-1.18 biome fields found in the [Level](LevelV0) compound @@ -118,7 +118,7 @@ pub struct LevelV0 { /// Version-specific part of a [Chunk] compound #[derive(Debug, Deserialize)] #[serde(untagged)] -pub enum ChunkVariants { +pub enum ChunkVariant { /// 1.18+ chunk data V1_18 { /// List of chunk sections @@ -140,7 +140,7 @@ pub struct Chunk { pub data_version: Option, /// Version-specific chunk data #[serde(flatten)] - pub chunk: ChunkVariants, + pub chunk: ChunkVariant, } /// `Data` compound element of level.dat From 4574c06f5d14021e2315125f9fe3d3ccde737ced Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 21:47:17 +0100 Subject: [PATCH 291/460] core/common: remove Clone from ProcessedChunk/ProcessedRegion These can be rather large, and there is no reason to ever clone them. --- 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 a6d9a44..471bef3 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -53,7 +53,7 @@ impl TileCoordMap { } /// Data structure for storing chunk data between processing and rendering steps -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct ProcessedChunk { /// Block type data pub blocks: Box, @@ -64,7 +64,7 @@ pub struct ProcessedChunk { } /// Data structure for storing region data between processing and rendering steps -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct ProcessedRegion { /// List of biomes used in the region /// From fa15a4e6e51b3a381b905ed5007121bcf981196b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 22:11:44 +0100 Subject: [PATCH 292/460] core/common: separate FileMetaVersion for different outputs --- src/core/common.rs | 12 +++++++++--- src/core/region_processor.rs | 8 ++++---- src/core/tile_mipmapper.rs | 8 ++++++-- src/core/tile_renderer.rs | 4 ++-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/core/common.rs b/src/core/common.rs index 471bef3..39c8e54 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -11,10 +11,16 @@ use serde::{Deserialize, Serialize}; use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; -/// MinedMap data version number -/// /// Increase to force regeneration of all output files -pub const FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + +/// MinedMap processed region data version number +pub const REGION_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + +/// MinedMap map tile data version number +pub const MAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); + +/// MinedMap lightmap data version number +pub const LIGHTMAP_FILE_META_VERSION: FileMetaVersion = FileMetaVersion(0); /// Coordinate pair of a generated tile /// diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 6442da0..830b0f2 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -126,7 +126,7 @@ impl<'a> RegionProcessor<'a> { processed_region: &ProcessedRegion, timestamp: SystemTime, ) -> Result<()> { - storage::write(path, processed_region, FILE_META_VERSION, timestamp) + storage::write(path, processed_region, REGION_FILE_META_VERSION, timestamp) } /// Saves a lightmap tile @@ -137,7 +137,7 @@ impl<'a> RegionProcessor<'a> { lightmap: &image::GrayAlphaImage, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp(path, FILE_META_VERSION, timestamp, |file| { + fs::create_with_timestamp(path, LIGHTMAP_FILE_META_VERSION, timestamp, |file| { lightmap .write_to(file, image::ImageFormat::Png) .context("Failed to save image") @@ -156,9 +156,9 @@ impl<'a> RegionProcessor<'a> { let input_timestamp = fs::modified_timestamp(&input_path)?; let output_path = self.config.processed_path(coords); - let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); + let output_timestamp = fs::read_timestamp(&output_path, REGION_FILE_META_VERSION); let lightmap_path = self.config.tile_path(TileKind::Lightmap, 0, coords); - let lightmap_timestamp = fs::read_timestamp(&lightmap_path, FILE_META_VERSION); + let lightmap_timestamp = fs::read_timestamp(&lightmap_path, LIGHTMAP_FILE_META_VERSION); if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp { diff --git a/src/core/tile_mipmapper.rs b/src/core/tile_mipmapper.rs index cc1a8d4..355bd23 100644 --- a/src/core/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -70,8 +70,12 @@ 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, FILE_META_VERSION); + let output_timestamp = fs::read_timestamp(&output_path, version); let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] .into_iter() @@ -145,7 +149,7 @@ impl<'a> TileMipmapper<'a> { ); } - fs::create_with_timestamp(&output_path, FILE_META_VERSION, input_timestamp, |file| { + fs::create_with_timestamp(&output_path, version, input_timestamp, |file| { image .write_to(file, image::ImageFormat::Png) .context("Failed to save image") diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 219e7c8..34f0310 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -270,7 +270,7 @@ impl<'a> TileRenderer<'a> { let (processed_paths, processed_timestamp) = self.processed_sources(coords)?; let output_path = self.config.tile_path(TileKind::Map, 0, coords); - let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); + let output_timestamp = fs::read_timestamp(&output_path, MAP_FILE_META_VERSION); if Some(processed_timestamp) <= output_timestamp { debug!( @@ -300,7 +300,7 @@ impl<'a> TileRenderer<'a> { fs::create_with_timestamp( &output_path, - FILE_META_VERSION, + MAP_FILE_META_VERSION, processed_timestamp, |file| { image From a5ad057e0cb4dc742c0603b1f025bf79e4c9bac1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 22:54:08 +0100 Subject: [PATCH 293/460] core/region_processor: refactor RegionProcessor::process_region() --- src/core/region_processor.rs | 317 ++++++++++++++++++++--------------- 1 file changed, 185 insertions(+), 132 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 830b0f2..712436f 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,21 +1,22 @@ //! The [RegionProcessor] and related functions -use std::{ffi::OsStr, path::Path, sync::mpsc, time::SystemTime}; +use std::{ + ffi::OsStr, + path::{Path, PathBuf}, + sync::mpsc, + time::SystemTime, +}; use anyhow::{Context, Result}; -use indexmap::IndexSet; use rayon::prelude::*; use tracing::{debug, info, warn}; use super::common::*; use crate::{ io::{fs, storage}, - resource::{self, Biome}, + resource, types::*, - world::{ - self, - layer::{self, LayerData}, - }, + world::{self, layer}, }; /// Parses a filename in the format r.X.Z.mca into the contained X and Z values @@ -44,6 +45,182 @@ enum RegionProcessorStatus { ErrorMissing, } +/// Handles processing for a single region +struct SingleRegionProcessor<'a> { + /// Registry of known block types + block_types: &'a resource::BlockTypes, + /// Registry of known biome types + biome_types: &'a resource::BiomeTypes, + /// Coordinates of the region this instance is processing + coords: TileCoords, + /// Input region filename + input_path: PathBuf, + /// Processed region data output filename + output_path: PathBuf, + /// Lightmap output filename + lightmap_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, + /// Processed region intermediate data + processed_region: ProcessedRegion, + /// Lightmap intermediate data + lightmap: image::GrayAlphaImage, +} + +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)?; + + 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 processed_region = ProcessedRegion::default(); + let lightmap = image::GrayAlphaImage::new(N, N); + + Ok(SingleRegionProcessor { + block_types: &processor.block_types, + biome_types: &processor.biome_types, + coords, + input_path, + output_path, + lightmap_path, + input_timestamp, + output_timestamp, + lightmap_timestamp, + processed_region, + lightmap, + }) + } + + /// Renders a lightmap subtile from chunk block light data + fn render_chunk_lightmap( + block_light: Box, + ) -> image::GrayAlphaImage { + /// Width/height of generated chunk lightmap + const N: u32 = BLOCKS_PER_CHUNK as u32; + + image::GrayAlphaImage::from_fn(N, N, |x, z| { + let v: f32 = block_light[LayerBlockCoords { + x: BlockX::new(x), + z: BlockZ::new(z), + }] + .into(); + image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) + }) + } + + /// Saves processed region data + /// + /// The timestamp is the time of the last modification of the input region data. + fn save_region( + path: &Path, + processed_region: &ProcessedRegion, + timestamp: SystemTime, + ) -> Result<()> { + storage::write(path, processed_region, REGION_FILE_META_VERSION, timestamp) + } + + /// Saves a lightmap tile + /// + /// The timestamp is the time of the last modification of the input region data. + fn save_lightmap( + path: &Path, + lightmap: &image::GrayAlphaImage, + timestamp: SystemTime, + ) -> Result<()> { + fs::create_with_timestamp(path, LIGHTMAP_FILE_META_VERSION, timestamp, |file| { + lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) + } + + /// Processes the region + fn run(mut self) -> Result { + if Some(self.input_timestamp) <= self.output_timestamp + && Some(self.input_timestamp) <= self.lightmap_timestamp + { + debug!( + "Skipping unchanged region r.{}.{}.mca", + self.coords.x, self.coords.z + ); + return Ok(RegionProcessorStatus::Skipped); + } + + debug!( + "Processing region r.{}.{}.mca", + self.coords.x, self.coords.z + ); + + if let Err(err) = (|| -> Result<()> { + crate::nbt::region::from_file(&self.input_path)?.foreach_chunk( + |chunk_coords, data: world::de::Chunk| { + let chunk = world::chunk::Chunk::new(&data, self.block_types, self.biome_types) + .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; + 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(()); + }; + self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { + blocks, + biomes, + depths, + })); + + let chunk_lightmap = Self::render_chunk_lightmap(block_light); + overlay_chunk(&mut self.lightmap, &chunk_lightmap, chunk_coords); + + Ok(()) + }, + ) + })() { + if self.output_timestamp.is_some() && self.lightmap_timestamp.is_some() { + warn!( + "Failed to process region {:?}, using old data: {:?}", + self.coords, err + ); + return Ok(RegionProcessorStatus::ErrorOk); + } else { + warn!( + "Failed to process region {:?}, no old data available: {:?}", + self.coords, err + ); + return Ok(RegionProcessorStatus::ErrorMissing); + } + } + + if Some(self.input_timestamp) > self.output_timestamp { + Self::save_region( + &self.output_path, + &self.processed_region, + self.input_timestamp, + )?; + } + if Some(self.input_timestamp) > self.lightmap_timestamp { + Self::save_lightmap(&self.lightmap_path, &self.lightmap, self.input_timestamp)?; + } + + Ok(RegionProcessorStatus::Ok) + } +} + /// Type with methods for processing the regions of a Minecraft save directory /// /// The RegionProcessor builds lightmap tiles as well as processed region data @@ -91,133 +268,9 @@ impl<'a> RegionProcessor<'a> { .collect()) } - /// Processes a single chunk - fn process_chunk( - &self, - biome_list: &mut IndexSet, - data: world::de::Chunk, - ) -> Result> { - let chunk = world::chunk::Chunk::new(&data, &self.block_types, &self.biome_types)?; - world::layer::top_layer(biome_list, &chunk) - } - - /// Renders a lightmap subtile from chunk block light data - fn render_chunk_lightmap( - block_light: Box, - ) -> image::GrayAlphaImage { - /// Width/height of generated chunk lightmap - const N: u32 = BLOCKS_PER_CHUNK as u32; - - image::GrayAlphaImage::from_fn(N, N, |x, z| { - let v: f32 = block_light[LayerBlockCoords { - x: BlockX::new(x), - z: BlockZ::new(z), - }] - .into(); - image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8]) - }) - } - - /// Saves processed region data - /// - /// The timestamp is the time of the last modification of the input region data. - fn save_region( - path: &Path, - processed_region: &ProcessedRegion, - timestamp: SystemTime, - ) -> Result<()> { - storage::write(path, processed_region, REGION_FILE_META_VERSION, timestamp) - } - - /// Saves a lightmap tile - /// - /// The timestamp is the time of the last modification of the input region data. - fn save_lightmap( - path: &Path, - lightmap: &image::GrayAlphaImage, - timestamp: SystemTime, - ) -> Result<()> { - fs::create_with_timestamp(path, LIGHTMAP_FILE_META_VERSION, timestamp, |file| { - lightmap - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }) - } - /// Processes a single region file fn process_region(&self, coords: TileCoords) -> Result { - /// Width/height of the region data - const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - - let mut processed_region = ProcessedRegion::default(); - let mut lightmap = image::GrayAlphaImage::new(N, N); - - let input_path = self.config.region_path(coords); - let input_timestamp = fs::modified_timestamp(&input_path)?; - - let output_path = self.config.processed_path(coords); - let output_timestamp = fs::read_timestamp(&output_path, REGION_FILE_META_VERSION); - let lightmap_path = self.config.tile_path(TileKind::Lightmap, 0, coords); - let lightmap_timestamp = fs::read_timestamp(&lightmap_path, LIGHTMAP_FILE_META_VERSION); - - if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp - { - debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); - return Ok(RegionProcessorStatus::Skipped); - } - - debug!("Processing region r.{}.{}.mca", coords.x, coords.z); - - if let Err(err) = (|| -> Result<()> { - crate::nbt::region::from_file(input_path)?.foreach_chunk( - |chunk_coords, data: world::de::Chunk| { - let Some(layer::LayerData { - blocks, - biomes, - block_light, - depths, - }) = self - .process_chunk(&mut processed_region.biome_list, data) - .with_context(|| format!("Failed to process chunk {:?}", chunk_coords))? - else { - return Ok(()); - }; - processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { - blocks, - biomes, - depths, - })); - - let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut lightmap, &chunk_lightmap, chunk_coords); - - Ok(()) - }, - ) - })() { - if output_timestamp.is_some() && lightmap_timestamp.is_some() { - warn!( - "Failed to process region {:?}, using old data: {:?}", - coords, err - ); - return Ok(RegionProcessorStatus::ErrorOk); - } else { - warn!( - "Failed to process region {:?}, no old data available: {:?}", - coords, err - ); - return Ok(RegionProcessorStatus::ErrorMissing); - } - } - - if Some(input_timestamp) > output_timestamp { - Self::save_region(&output_path, &processed_region, input_timestamp)?; - } - if Some(input_timestamp) > lightmap_timestamp { - Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; - } - - Ok(RegionProcessorStatus::Ok) + SingleRegionProcessor::new(self, coords)?.run() } /// Iterates over all region files of a Minecraft save directory From 25f675bd3b3e62b917175beb9eea55bb12ff7932 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 22:16:56 +0100 Subject: [PATCH 294/460] core/region_processor: make logic for skipping updates more fine-grained Allow skipping parts of the processing separately for processed region and lightmap files. --- src/core/region_processor.rs | 37 ++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 712436f..52b9e7d 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -65,6 +65,10 @@ struct SingleRegionProcessor<'a> { output_timestamp: Option, /// Timestamp of last modification of lightmap output file (if valid) lightmap_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, /// Processed region intermediate data processed_region: ProcessedRegion, /// Lightmap intermediate data @@ -85,6 +89,9 @@ impl<'a> SingleRegionProcessor<'a> { let lightmap_path = processor.config.tile_path(TileKind::Lightmap, 0, coords); let lightmap_timestamp = fs::read_timestamp(&lightmap_path, LIGHTMAP_FILE_META_VERSION); + let output_needed = Some(input_timestamp) > output_timestamp; + let lightmap_needed = Some(input_timestamp) > lightmap_timestamp; + let processed_region = ProcessedRegion::default(); let lightmap = image::GrayAlphaImage::new(N, N); @@ -98,6 +105,8 @@ impl<'a> SingleRegionProcessor<'a> { input_timestamp, output_timestamp, lightmap_timestamp, + output_needed, + lightmap_needed, processed_region, lightmap, }) @@ -148,9 +157,7 @@ impl<'a> SingleRegionProcessor<'a> { /// Processes the region fn run(mut self) -> Result { - if Some(self.input_timestamp) <= self.output_timestamp - && Some(self.input_timestamp) <= self.lightmap_timestamp - { + if !self.output_needed && !self.lightmap_needed { debug!( "Skipping unchanged region r.{}.{}.mca", self.coords.x, self.coords.z @@ -178,14 +185,20 @@ impl<'a> SingleRegionProcessor<'a> { else { return Ok(()); }; - self.processed_region.chunks[chunk_coords] = Some(Box::new(ProcessedChunk { - blocks, - biomes, - depths, - })); - let chunk_lightmap = Self::render_chunk_lightmap(block_light); - overlay_chunk(&mut self.lightmap, &chunk_lightmap, 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); + } Ok(()) }, @@ -206,14 +219,14 @@ impl<'a> SingleRegionProcessor<'a> { } } - if Some(self.input_timestamp) > self.output_timestamp { + if self.output_needed { Self::save_region( &self.output_path, &self.processed_region, self.input_timestamp, )?; } - if Some(self.input_timestamp) > self.lightmap_timestamp { + if self.lightmap_needed { Self::save_lightmap(&self.lightmap_path, &self.lightmap, self.input_timestamp)?; } From 93c1ce943714cad655cc324a4723e323010b2090 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 25 Nov 2023 23:03:13 +0100 Subject: [PATCH 295/460] core/region_processor: further split up SingleRegionProcessor::run() --- src/core/region_processor.rs | 133 ++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/src/core/region_processor.rs b/src/core/region_processor.rs index 52b9e7d..9e1bb65 100644 --- a/src/core/region_processor.rs +++ b/src/core/region_processor.rs @@ -1,11 +1,6 @@ //! The [RegionProcessor] and related functions -use std::{ - ffi::OsStr, - path::{Path, PathBuf}, - sync::mpsc, - time::SystemTime, -}; +use std::{ffi::OsStr, path::PathBuf, sync::mpsc, time::SystemTime}; use anyhow::{Context, Result}; use rayon::prelude::*; @@ -132,27 +127,74 @@ 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( - path: &Path, - processed_region: &ProcessedRegion, - timestamp: SystemTime, - ) -> Result<()> { - storage::write(path, processed_region, REGION_FILE_META_VERSION, timestamp) + fn save_region(&self) -> Result<()> { + if !self.output_needed { + return Ok(()); + } + + storage::write( + &self.output_path, + &self.processed_region, + REGION_FILE_META_VERSION, + self.input_timestamp, + ) } /// Saves a lightmap tile /// /// The timestamp is the time of the last modification of the input region data. - fn save_lightmap( - path: &Path, - lightmap: &image::GrayAlphaImage, - timestamp: SystemTime, - ) -> Result<()> { - fs::create_with_timestamp(path, LIGHTMAP_FILE_META_VERSION, timestamp, |file| { - lightmap - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }) + fn save_lightmap(&self) -> Result<()> { + if !self.lightmap_needed { + return Ok(()); + } + + fs::create_with_timestamp( + &self.lightmap_path, + LIGHTMAP_FILE_META_VERSION, + self.input_timestamp, + |file| { + self.lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }, + ) + } + + /// 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 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 { + 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); + } + + 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)) } /// Processes the region @@ -170,40 +212,7 @@ impl<'a> SingleRegionProcessor<'a> { self.coords.x, self.coords.z ); - if let Err(err) = (|| -> Result<()> { - crate::nbt::region::from_file(&self.input_path)?.foreach_chunk( - |chunk_coords, data: world::de::Chunk| { - let chunk = world::chunk::Chunk::new(&data, self.block_types, self.biome_types) - .with_context(|| format!("Failed to decode chunk {:?}", chunk_coords))?; - 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 { - 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); - } - - Ok(()) - }, - ) - })() { + if let Err(err) = self.process_chunks() { if self.output_timestamp.is_some() && self.lightmap_timestamp.is_some() { warn!( "Failed to process region {:?}, using old data: {:?}", @@ -219,16 +228,8 @@ impl<'a> SingleRegionProcessor<'a> { } } - if self.output_needed { - Self::save_region( - &self.output_path, - &self.processed_region, - self.input_timestamp, - )?; - } - if self.lightmap_needed { - Self::save_lightmap(&self.lightmap_path, &self.lightmap, self.input_timestamp)?; - } + self.save_region()?; + self.save_lightmap()?; Ok(RegionProcessorStatus::Ok) } From 1432df7c936927b051ab40f2630ab372fa659115 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Dec 2023 20:06:52 +0100 Subject: [PATCH 296/460] Update dependencies --- Cargo.lock | 236 ++++++++++++++++++++++--------------- Cargo.toml | 2 +- crates/resource/Cargo.toml | 2 +- 3 files changed, 143 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95ee246..b76fb71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,9 +37,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -57,27 +57,27 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", "windows-sys", @@ -85,9 +85,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9" [[package]] name = "autocfg" @@ -161,9 +161,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.4.8" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" dependencies = [ "clap_builder", "clap_derive", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" dependencies = [ "anstream", "anstyle", @@ -231,9 +231,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -242,22 +242,20 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" dependencies = [ "cfg-if", ] @@ -309,9 +307,9 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" +checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" dependencies = [ "simd-adler32", ] @@ -329,15 +327,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -346,15 +344,15 @@ dependencies = [ [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-macro", @@ -366,24 +364,24 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git-version" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ad01ffa8221f7fe8b936d6ffb2a3e7ad428885a04fad51866a5f33eafda57c" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" dependencies = [ "git-version-macro", ] [[package]] name = "git-version-macro" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84488ccbdb24ad6f56dc1863b4a8154a7856cd3c6c7610401634fab3cb588dae" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", @@ -392,15 +390,15 @@ dependencies = [ [[package]] name = "glam" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" +checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3" [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -454,9 +452,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" @@ -475,9 +473,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libz-ng-sys" @@ -507,27 +505,18 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" dependencies = [ "hashbrown", ] [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "minedmap" @@ -650,18 +639,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "overload" @@ -689,7 +678,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -706,9 +695,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "png" @@ -725,9 +714,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" dependencies = [ "unicode-ident", ] @@ -784,9 +773,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "scopeguard" @@ -796,27 +785,27 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8bb1879ea93538b78549031e2d54da3e901fd7e75f2e4dc758d760937b123d10" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -872,9 +861,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.39" +version = "2.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" dependencies = [ "proc-macro2", "quote", @@ -893,9 +882,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.34.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "parking_lot", @@ -1007,11 +996,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -1020,13 +1009,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +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", ] [[package]] @@ -1035,36 +1039,72 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -1072,19 +1112,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "zerocopy" -version = "0.7.26" +name = "windows_x86_64_msvc" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.26" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 468f0f4..a1d5daf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" -glam = "0.24.0" +glam = "0.25.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" diff --git a/crates/resource/Cargo.toml b/crates/resource/Cargo.toml index 78917da..b1bc005 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.24.1" +glam = "0.25.0" serde = { version = "1.0.183", features = ["derive"] } From 1812e5c6d636474a5891ce3ac632443e70cb654c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Dec 2023 20:13:03 +0100 Subject: [PATCH 297/460] Add type alias for f32 colors to minedmap-resource Allow removing the dependency on a specific glam version from the main crate. --- Cargo.lock | 1 - Cargo.toml | 1 - crates/resource/src/block_color.rs | 52 ++++++++++++++---------------- crates/resource/src/lib.rs | 5 ++- src/core/tile_renderer.rs | 7 ++-- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b76fb71..f681a43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,7 +528,6 @@ dependencies = [ "fastnbt", "futures-util", "git-version", - "glam", "image", "indexmap", "lru", diff --git a/Cargo.toml b/Cargo.toml index a1d5daf..47c13c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,6 @@ clap = { version = "4.1.4", features = ["derive"] } fastnbt = "2.3.2" futures-util = "0.3.28" git-version = "0.3.5" -glam = "0.25.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } lru = "0.12.0" diff --git a/crates/resource/src/block_color.rs b/crates/resource/src/block_color.rs index 3df9a54..cffebeb 100644 --- a/crates/resource/src/block_color.rs +++ b/crates/resource/src/block_color.rs @@ -1,16 +1,14 @@ //! Functions for computations of block colors -use super::{Biome, BlockType, Color}; - -use glam::Vec3; +use super::{Biome, BlockType, Color, Colorf}; /// Converts an u8 RGB color to a float vector -fn color_vec_unscaled(color: Color) -> Vec3 { - Vec3::from_array(color.0.map(f32::from)) +fn color_vec_unscaled(color: Color) -> Colorf { + Colorf::from_array(color.0.map(f32::from)) } /// Converts an u8 RGB color to a float vector, scaling the components to 0.0..1.0 -fn color_vec(color: Color) -> Vec3 { +fn color_vec(color: Color) -> Colorf { color_vec_unscaled(color) / 255.0 } @@ -18,7 +16,7 @@ fn color_vec(color: Color) -> Vec3 { /// /// Biome temperature and downfall are modified based on the depth value /// before using them to compute the final color -fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { +fn color_from_params(colors: &[Colorf; 3], biome: &Biome, depth: f32) -> Colorf { let temp = (biome.temp() - f32::max((depth - 64.0) / 600.0, 0.0)).clamp(0.0, 1.0); let downfall = biome.downfall().clamp(0.0, 1.0) * temp; @@ -28,27 +26,27 @@ fn color_from_params(colors: &[Vec3; 3], biome: &Biome, depth: f32) -> Vec3 { /// Extension trait with helpers for computing biome-specific block colors trait BiomeExt { /// Returns the grass color of the biome at a given depth - fn grass_color(&self, depth: f32) -> Vec3; + fn grass_color(&self, depth: f32) -> Colorf; /// Returns the foliage color of the biome at a given depth - fn foliage_color(&self, depth: f32) -> Vec3; + fn foliage_color(&self, depth: f32) -> Colorf; /// Returns the water color of the biome - fn water_color(&self) -> Vec3; + fn water_color(&self) -> Colorf; } impl BiomeExt for Biome { - fn grass_color(&self, depth: f32) -> Vec3 { + fn grass_color(&self, depth: f32) -> Colorf { use super::BiomeGrassColorModifier::*; /// Color matrix extracted from grass color texture - const GRASS_COLORS: [Vec3; 3] = [ - Vec3::new(0.502, 0.706, 0.592), // lower right - Vec3::new(0.247, 0.012, -0.259), // lower left - lower right - Vec3::new(-0.471, 0.086, -0.133), // upper left - lower left + const GRASS_COLORS: [Colorf; 3] = [ + Colorf::new(0.502, 0.706, 0.592), // lower right + Colorf::new(0.247, 0.012, -0.259), // lower left - lower right + Colorf::new(-0.471, 0.086, -0.133), // upper left - lower left ]; /// Used for dark forst grass color modifier - const DARK_FOREST_GRASS_COLOR: Vec3 = Vec3::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) + const DARK_FOREST_GRASS_COLOR: Colorf = Colorf::new(0.157, 0.204, 0.039); // == color_vec(Color([40, 52, 10])) /// Grass color in swamp biomes - const SWAMP_GRASS_COLOR: Vec3 = Vec3::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) + const SWAMP_GRASS_COLOR: Colorf = Colorf::new(0.416, 0.439, 0.224); // == color_vec(Color([106, 112, 57])) let regular_color = || { self.grass_color @@ -63,12 +61,12 @@ impl BiomeExt for Biome { } } - fn foliage_color(&self, depth: f32) -> Vec3 { + fn foliage_color(&self, depth: f32) -> Colorf { /// Color matrix extracted from foliage color texture - const FOLIAGE_COLORS: [Vec3; 3] = [ - Vec3::new(0.376, 0.631, 0.482), // lower right - Vec3::new(0.306, 0.012, -0.317), // lower left - lower right - Vec3::new(-0.580, 0.106, -0.165), // upper left - lower left + const FOLIAGE_COLORS: [Colorf; 3] = [ + Colorf::new(0.376, 0.631, 0.482), // lower right + Colorf::new(0.306, 0.012, -0.317), // lower left - lower right + Colorf::new(-0.580, 0.106, -0.165), // upper left - lower left ]; self.foliage_color @@ -76,11 +74,11 @@ impl BiomeExt for Biome { .unwrap_or_else(|| color_from_params(&FOLIAGE_COLORS, self, depth)) } - fn water_color(&self) -> Vec3 { + fn water_color(&self) -> Colorf { /// Default biome water color /// /// Used for biomes that don't explicitly set a water color - const DEFAULT_WATER_COLOR: Vec3 = Vec3::new(0.247, 0.463, 0.894); // == color_vec(Color([63, 118, 228])) + const DEFAULT_WATER_COLOR: Colorf = Colorf::new(0.247, 0.463, 0.894); // == color_vec(Color([63, 118, 228])) self.water_color .map(color_vec) @@ -89,9 +87,9 @@ impl BiomeExt for Biome { } /// Color multiplier for birch leaves -const BIRCH_COLOR: Vec3 = Vec3::new(0.502, 0.655, 0.333); // == color_vec(Color([128, 167, 85])) +const BIRCH_COLOR: Colorf = Colorf::new(0.502, 0.655, 0.333); // == color_vec(Color([128, 167, 85])) /// Color multiplier for spruce leaves -const EVERGREEN_COLOR: Vec3 = Vec3::new(0.380, 0.600, 0.380); // == color_vec(Color([97, 153, 97])) +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 { @@ -104,7 +102,7 @@ pub fn needs_biome(block: BlockType) -> bool { /// /// [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) -> Vec3 { +pub fn block_color(block: BlockType, 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/lib.rs b/crates/resource/src/lib.rs index 5423bd7..a832a58 100644 --- a/crates/resource/src/lib.rs +++ b/crates/resource/src/lib.rs @@ -33,10 +33,13 @@ pub enum BlockFlag { Water, } -/// An RGB color +/// An RGB color with u8 components #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] 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)] pub struct BlockType { diff --git a/src/core/tile_renderer.rs b/src/core/tile_renderer.rs index 34f0310..b341076 100644 --- a/src/core/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -8,7 +8,6 @@ use std::{ }; use anyhow::{Context, Result}; -use glam::Vec3; use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; @@ -17,7 +16,7 @@ use tracing::{debug, info}; use super::{common::*, region_group::RegionGroup}; use crate::{ io::{fs, storage}, - resource::{block_color, needs_biome}, + resource::{block_color, needs_biome, Colorf}, types::*, util::coord_offset, }; @@ -128,7 +127,7 @@ impl<'a> TileRenderer<'a> { chunk: &ProcessedChunk, chunk_coords: ChunkCoords, block_coords: LayerBlockCoords, - ) -> Option { + ) -> Option { /// Helper for keys in the weight table /// /// Hashing the value as a single u32 is more efficient than hashing @@ -182,7 +181,7 @@ impl<'a> TileRenderer<'a> { return None; } - let mut color = Vec3::ZERO; + let mut color = Colorf::ZERO; let mut total = 0.0; for ((region_x, region_z, index), w) in weights.into_values() { From fdf44ebc8039b1471ccf004119c62cd4b9fa2153 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 3 Jan 2024 02:18:33 +0100 Subject: [PATCH 298/460] viewer: update to use "modern" ECMAScript features --- viewer/MinedMap.js | 63 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 0ced720..94e5ff8 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -1,10 +1,10 @@ // bsearch-based array element check function contains(array, elem) { - var min = 0, max = array.length, i, cur; + let min = 0, max = array.length; while (min < max) { - i = min + Math.floor((max-min)/2); - cur = array[i]; + const i = min + Math.floor((max-min)/2); + const cur = array[i]; if (cur === elem) return true; @@ -17,7 +17,7 @@ function contains(array, elem) { return false; } -var MinedMapLayer = L.GridLayer.extend({ +const MinedMapLayer = L.GridLayer.extend({ initialize: function (mipmaps, layer) { this.mipmaps = mipmaps; this.layer = layer; @@ -37,7 +37,7 @@ var MinedMapLayer = L.GridLayer.extend({ }, createTile: function (coords, done) { - var tile = document.createElement('img'); + const tile = document.createElement('img'); tile.onload = L.bind(this._tileOnLoad, this, done, tile); tile.onerror = L.bind(this._tileOnError, this, done, tile); @@ -54,11 +54,11 @@ var MinedMapLayer = L.GridLayer.extend({ */ tile.setAttribute('role', 'presentation'); - var z = -(coords.z + this.zoomOffset); + let z = -(coords.z + this.zoomOffset); if (z < 0) z = 0; - var mipmap = this.mipmaps[z]; + const mipmap = this.mipmaps[z]; if (coords.x >= mipmap.bounds.minX && coords.x <= mipmap.bounds.maxX && coords.y >= mipmap.bounds.minZ && coords.y <= mipmap.bounds.maxZ && @@ -87,10 +87,9 @@ var MinedMapLayer = L.GridLayer.extend({ }, _abortLoading: function () { - var i, tile; - for (i in this._tiles) { + for (const i in this._tiles) { if (this._tiles[i].coords.z !== this._tileZoom) { - tile = this._tiles[i].el; + const tile = this._tiles[i].el; tile.onload = L.Util.falseFn; tile.onerror = L.Util.falseFn; @@ -104,7 +103,7 @@ var MinedMapLayer = L.GridLayer.extend({ }, _removeTile: function (key) { - var tile = this._tiles[key]; + const tile = this._tiles[key]; if (!tile) { return; } // Cancels any pending http requests associated with the tile @@ -119,7 +118,7 @@ var MinedMapLayer = L.GridLayer.extend({ }); -var CoordControl = L.Control.extend({ +const CoordControl = L.Control.extend({ initialize: function () { this.options.position = 'bottomleft'; }, @@ -138,15 +137,15 @@ var CoordControl = L.Control.extend({ }); -var parseHash = function () { - var args = {}; +const parseHash = function () { + const args = {}; if (window.location.hash) { - var parts = window.location.hash.substr(1).split('&'); + const parts = window.location.hash.substring(1).split('&'); - for (var i = 0; i < parts.length; i++) { - var key_value = parts[i].split('='); - var key = key_value[0], value = key_value.slice(1).join('='); + for (const part of parts) { + const key_value = part.split('='); + const key = key_value[0], value = key_value.slice(1).join('='); args[key] = value; } @@ -157,16 +156,16 @@ var parseHash = function () { window.createMap = function () { - var xhr = new XMLHttpRequest(); + const xhr = new XMLHttpRequest(); xhr.onload = function () { - var res = JSON.parse(this.responseText), + const res = JSON.parse(this.responseText), mipmaps = res.mipmaps, spawn = res.spawn; - var x, z, zoom, light; + let x, z, zoom, light; - var updateParams = function () { - var args = parseHash(); + const updateParams = function () { + const args = parseHash(); zoom = parseInt(args['zoom']); x = parseFloat(args['x']); @@ -183,7 +182,7 @@ window.createMap = function () { updateParams(); - var map = L.map('map', { + const map = L.map('map', { center: [-z, x], zoom: zoom, minZoom: -(mipmaps.length-1), @@ -195,29 +194,29 @@ window.createMap = function () { ], }); - var mapLayer = new MinedMapLayer(mipmaps, 'map'); - var lightLayer = new MinedMapLayer(mipmaps, 'light'); + const mapLayer = new MinedMapLayer(mipmaps, 'map'); + const lightLayer = new MinedMapLayer(mipmaps, 'light'); mapLayer.addTo(map); if (light) map.addLayer(lightLayer); - var overlayMaps = { + const overlayMaps = { "Illumination": lightLayer, }; L.control.layers({}, overlayMaps).addTo(map); - var coordControl = new CoordControl(); + const coordControl = new CoordControl(); coordControl.addTo(map); map.on('mousemove', function(e) { coordControl.update(Math.round(e.latlng.lng), Math.round(-e.latlng.lat)); }); - var makeHash = function () { - var ret = '#x='+x+'&z='+z; + const makeHash = function () { + let ret = '#x='+x+'&z='+z; if (zoom != 0) ret += '&zoom='+zoom; @@ -228,11 +227,11 @@ window.createMap = function () { return ret; }; - var updateHash = function () { + const updateHash = function () { window.location.hash = makeHash(); }; - var refreshHash = function () { + const refreshHash = function () { zoom = map.getZoom(); center = map.getCenter(); x = Math.round(center.lng); From a8e0af287b099e15affa90caa923b6e526968f2e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 3 Jan 2024 02:22:54 +0100 Subject: [PATCH 299/460] viewer: update attribution link --- viewer/MinedMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 94e5ff8..8cd4d67 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -25,7 +25,7 @@ const MinedMapLayer = L.GridLayer.extend({ this.zoomOffset = L.Browser.retina ? 1 : 0; this.options.tileSize = L.Browser.retina ? 256 : 512; - this.options.attribution = 'Generated by MinedMap'; + this.options.attribution = 'Generated by MinedMap'; this.options.minZoom = -(mipmaps.length-1 + this.zoomOffset); this.options.maxNativeZoom = -this.zoomOffset; From cb7f428974ed75e5f9bcc2088a9d7335a2a4a3d3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 3 Jan 2024 04:05:41 +0100 Subject: [PATCH 300/460] viewer: update to leaflet 1.9.4 --- viewer/MinedMap.js | 106 ++++------------- viewer/index.html | 4 +- viewer/leaflet-1.6.0/leaflet.js | 5 - viewer/leaflet-1.6.0/leaflet.js.map | 1 - .../images/layers-2x.png | Bin .../images/layers.png | Bin .../images/marker-icon-2x.png | Bin .../images/marker-icon.png | Bin .../images/marker-shadow.png | Bin .../leaflet.css | 107 +++++++++++------- viewer/leaflet-1.9.4/leaflet.js | 6 + viewer/leaflet-1.9.4/leaflet.js.map | 1 + 12 files changed, 98 insertions(+), 132 deletions(-) delete mode 100644 viewer/leaflet-1.6.0/leaflet.js delete mode 100644 viewer/leaflet-1.6.0/leaflet.js.map rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/images/layers-2x.png (100%) rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/images/layers.png (100%) rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/images/marker-icon-2x.png (100%) rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/images/marker-icon.png (100%) rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/images/marker-shadow.png (100%) rename viewer/{leaflet-1.6.0 => leaflet-1.9.4}/leaflet.css (84%) create mode 100644 viewer/leaflet-1.9.4/leaflet.js create mode 100644 viewer/leaflet-1.9.4/leaflet.js.map diff --git a/viewer/MinedMap.js b/viewer/MinedMap.js index 8cd4d67..1288dc9 100644 --- a/viewer/MinedMap.js +++ b/viewer/MinedMap.js @@ -17,103 +17,47 @@ function contains(array, elem) { return false; } -const MinedMapLayer = L.GridLayer.extend({ +const MinedMapLayer = L.TileLayer.extend({ initialize: function (mipmaps, layer) { + L.TileLayer.prototype.initialize.call(this, '', { + detectRetina: true, + tileSize: 512, + zoomReverse: true, + minZoom: -(mipmaps.length-1), + maxZoom: 0, + attribution: 'Generated by MinedMap', + }); + + this.options.maxNativeZoom = this.options.maxZoom; + this.options.maxZoom = undefined; + this.mipmaps = mipmaps; this.layer = layer; - - this.zoomOffset = L.Browser.retina ? 1 : 0; - - this.options.tileSize = L.Browser.retina ? 256 : 512; - this.options.attribution = 'Generated by MinedMap'; - - this.options.minZoom = -(mipmaps.length-1 + this.zoomOffset); - this.options.maxNativeZoom = -this.zoomOffset; - - // for https://github.com/Leaflet/Leaflet/issues/137 - if (!L.Browser.android) { - this.on('tileunload', this._onTileRemove); - } }, createTile: function (coords, done) { - const tile = document.createElement('img'); + const tile = L.TileLayer.prototype.createTile.call(this, coords, done); - tile.onload = L.bind(this._tileOnLoad, this, done, tile); - tile.onerror = L.bind(this._tileOnError, this, done, tile); - - /* - Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons - http://www.w3.org/TR/WCAG20-TECHS/H67 - */ - tile.alt = ''; - - /* - Set role="presentation" to force screen readers to ignore this - https://www.w3.org/TR/wai-aria/roles#textalternativecomputation - */ - tile.setAttribute('role', 'presentation'); - - let z = -(coords.z + this.zoomOffset); - if (z < 0) - z = 0; - - const mipmap = this.mipmaps[z]; - - if (coords.x >= mipmap.bounds.minX && coords.x <= mipmap.bounds.maxX && - coords.y >= mipmap.bounds.minZ && coords.y <= mipmap.bounds.maxZ && - contains(mipmap.regions[coords.y] || [], coords.x)) - tile.src = 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; - - if (z === 0) + if (coords.z - this.options.zoomOffset >= 0) L.DomUtil.addClass(tile, 'overzoomed'); return tile; }, - _tileOnLoad: function (done, tile) { - if (L.Browser.ielt9) - setTimeout(Util.bind(done, this, null, tile), 0); - else - done(null, tile); - }, + getTileUrl: function (coords) { + let z = -coords.z + this.options.zoomOffset; + if (z < 0) + z = 0; - _tileOnError: function (done, tile, e) { - done(e, tile); - }, + const mipmap = this.mipmaps[z]; - _onTileRemove: function (e) { - e.tile.onload = null; - }, + if (coords.x < mipmap.bounds.minX || coords.x > mipmap.bounds.maxX || + coords.y < mipmap.bounds.minZ || coords.y > mipmap.bounds.maxZ || + !contains(mipmap.regions[coords.y] || [], coords.x)) + return L.Util.emptyImageUrl; - _abortLoading: function () { - for (const i in this._tiles) { - if (this._tiles[i].coords.z !== this._tileZoom) { - const tile = this._tiles[i].el; - tile.onload = L.Util.falseFn; - tile.onerror = L.Util.falseFn; - - if (!tile.complete) { - tile.src = L.Util.emptyImageUrl; - L.DomUtil.remove(tile); - } - } - } - }, - - _removeTile: function (key) { - const tile = this._tiles[key]; - if (!tile) { return; } - - // Cancels any pending http requests associated with the tile - // unless we're on Android's stock browser, - // see https://github.com/Leaflet/Leaflet/issues/137 - if (!L.Browser.androidStock) { - tile.el.setAttribute('src', L.Util.emptyImageUrl); - } - - return L.GridLayer.prototype._removeTile.call(this, key); + return 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png'; }, }); diff --git a/viewer/index.html b/viewer/index.html index 20b71b1..df57cb6 100644 --- a/viewer/index.html +++ b/viewer/index.html @@ -4,8 +4,8 @@ MinedMap - - + + From 7834315dd339555f6d5a5aa3e24e4ceba0802689 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 6 Jan 2024 22:59:37 +0100 Subject: [PATCH 343/460] 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 344/460] 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 345/460] 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 346/460] 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 347/460] 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 348/460] 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 349/460] 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 350/460] 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 351/460] 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 352/460] 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 353/460] 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 354/460] 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 355/460] 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 356/460] 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 357/460] 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 358/460] 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 359/460] 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 360/460] 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 361/460] 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 362/460] 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 363/460] 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 364/460] 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 365/460] 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 366/460] 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 367/460] 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 368/460] 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 369/460] 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 370/460] 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 371/460] 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 372/460] 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 373/460] 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 374/460] 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 375/460] 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 376/460] 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 377/460] 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 378/460] 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 379/460] 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 380/460] 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 381/460] 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 382/460] 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 383/460] 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 384/460] 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 385/460] 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 386/460] 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 387/460] 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 388/460] 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 389/460] 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 390/460] 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 391/460] 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 392/460] 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 393/460] 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 394/460] 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 395/460] 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 396/460] 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 397/460] 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 398/460] 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 399/460] 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 400/460] 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 401/460] 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 402/460] 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 403/460] 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 404/460] 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 405/460] 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 406/460] 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 407/460] 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 408/460] 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 409/460] 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 410/460] 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 411/460] 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 412/460] 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 413/460] 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 414/460] 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 415/460] 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 416/460] 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 417/460] 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 418/460] 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 419/460] 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 420/460] 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 421/460] 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 422/460] 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 423/460] 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 424/460] 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 425/460] 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 426/460] 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 427/460] 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 428/460] 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 429/460] 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 430/460] 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 431/460] 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 432/460] 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 433/460] 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 434/460] 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 435/460] 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 436/460] 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 437/460] 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 438/460] 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 439/460] 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 440/460] 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 441/460] 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 442/460] 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 443/460] 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 444/460] 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 445/460] 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 446/460] 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 447/460] 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 448/460] 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 449/460] 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 450/460] 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 451/460] 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 452/460] 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 453/460] 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 454/460] 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 455/460] 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 456/460] 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 457/460] 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 458/460] 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 459/460] 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 460/460] 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