Skip to content

Commit

Permalink
Merge PR #1759 from iRath96
Browse files Browse the repository at this point in the history
  • Loading branch information
CounterPillow committed May 22, 2020
2 parents dc6f8cf + 9e7bd98 commit 98f83af
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions overviewer_core/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import locale

import numpy
import math

from . import nbt
from . import cache
Expand Down Expand Up @@ -1177,7 +1178,7 @@ def _get_regionobj(self, regionfilename):
self.regioncache[regionfilename] = region
return region

def _packed_longarray_to_shorts(self, long_array, n):
def _packed_longarray_to_shorts(self, long_array, n, num_palette):
bits_per_value = (len(long_array) * 64) / n
if bits_per_value < 4 or 12 < bits_per_value:
raise nbt.CorruptChunkError()
Expand Down Expand Up @@ -1243,8 +1244,22 @@ def _packed_longarray_to_shorts(self, long_array, n):
result[1::2] = ( b[2::3] << 4) | ((b[1::3] & 0xf0) >> 4)

return result

def _packed_longarray_to_shorts_v116(self, long_array, n, num_palette):
bits_per_value = max(4, math.ceil(math.log2(num_palette)))

def _get_blockdata_v113(self, section, unrecognized_block_types):
b = numpy.asarray(long_array, dtype=numpy.uint64)
result = numpy.zeros((n,), dtype=numpy.uint16)
shorts_per_long = 64 // bits_per_value
mask = (1 << bits_per_value) - 1

for i in range(shorts_per_long):
j = (n + shorts_per_long - 1 - i) // shorts_per_long
result[i::shorts_per_long] = (b[:j] >> (bits_per_value * i)) & mask

return result

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.
num_palette_entries = len(section['Palette'])
translated_blocks = numpy.zeros((num_palette_entries,), dtype=numpy.uint16) # block IDs
Expand All @@ -1259,7 +1274,7 @@ def _get_blockdata_v113(self, section, unrecognized_block_types):
# Turn the BlockStates array into a 16x16x16 numpy matrix of shorts.
blocks = numpy.empty((4096,), dtype=numpy.uint16)
data = numpy.empty((4096,), dtype=numpy.uint8)
block_states = self._packed_longarray_to_shorts(section['BlockStates'], 4096)
block_states = longarray_unpacker(section['BlockStates'], 4096, num_palette_entries)
blocks[:] = translated_blocks[block_states]
data[:] = translated_data[block_states]

Expand Down Expand Up @@ -1373,6 +1388,11 @@ def get_chunk(self, x, z):
level = data[1]['Level']
chunk_data = level

longarray_unpacker = self._packed_longarray_to_shorts
if data[1].get('DataVersion', 0) >= 2529:
# starting with 1.16 snapshot 20w17a, block states are packed differently
longarray_unpacker = self._packed_longarray_to_shorts_v116

# From the interior of a map to the edge, a chunk's status may be one of:
# - postprocessed (interior, or next to fullchunk)
# - fullchunk (next to decorated)
Expand Down Expand Up @@ -1433,7 +1453,7 @@ def get_chunk(self, x, z):
section['BlockLight'] = blocklight_expanded

if 'Palette' in section:
(blocks, data) = self._get_blockdata_v113(section, unrecognized_block_types)
(blocks, data) = self._get_blockdata_v113(section, unrecognized_block_types, longarray_unpacker)
elif 'Data' in section:
(blocks, data) = self._get_blockdata_v112(section)
else: # Special case introduced with 1.14
Expand Down

0 comments on commit 98f83af

Please sign in to comment.