0

world: work around minecraft palette bugs

Instead of trusting that Minecraft will only request up to index
num_palette_entries - 1, we'll assume Mojang occasionally produces
a weird file where it tries to request past that, up to the maximum
palette index it can based on the bits per value. To facilitate this,
this commit extends the translation palette array to this maximum size.

Such invalid palette picks will simply be replaced by ID 0 (aka air),
so it should cause minimal weirdness in the output.

Works around #1797.
This commit is contained in:
Nicolas F
2020-07-09 18:33:39 +02:00
parent 8ec2a998e2
commit 8c0028495d

View File

@@ -1262,8 +1262,11 @@ class RegionSet(object):
def _get_blockdata_v113(self, section, unrecognized_block_types, longarray_unpacker): def _get_blockdata_v113(self, section, unrecognized_block_types, longarray_unpacker):
# Translate each entry in the palette to a 1.2-era (block, data) int pair. # Translate each entry in the palette to a 1.2-era (block, data) int pair.
num_palette_entries = len(section['Palette']) num_palette_entries = len(section['Palette'])
translated_blocks = numpy.zeros((num_palette_entries,), dtype=numpy.uint16) # block IDs # Due to Minecraft bugginess, we extend this array to contain zeroes all the way to the
translated_data = numpy.zeros((num_palette_entries,), dtype=numpy.uint8) # block data # maximum palette index Minecraft can request in Minecraft 1.16
next_pwr_two = 1 << math.ceil(math.log2(num_palette_entries))
translated_blocks = numpy.zeros((next_pwr_two,), dtype=numpy.uint16) # block IDs
translated_data = numpy.zeros((next_pwr_two,), dtype=numpy.uint8) # block data
for i in range(num_palette_entries): for i in range(num_palette_entries):
key = section['Palette'][i] key = section['Palette'][i]
try: try: