Skip to content
This repository has been archived by the owner on May 8, 2023. It is now read-only.

Commit

Permalink
Refactor the code and make it actually work
Browse files Browse the repository at this point in the history
Most of the code is done by @spiwn, and should hopefully fix #9.
Custom chunks (EmptyChunk) still use old format, but minecraft should be
able to convert to the newer one.
  • Loading branch information
matcool committed Jun 1, 2020
1 parent cc8c8af commit 24b45b5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 26 deletions.
54 changes: 29 additions & 25 deletions anvil/chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import math


# The version that removes block state value stretching from the storage
_Version_20w_17a = 2529
# This version removes block state value stretching from the storage
# so a block value isn't in multiple elements of the array
_VERSION_20w17a = 2529

def bin_append(a, b, length=None):
"""
Expand Down Expand Up @@ -37,10 +38,10 @@ class Chunk:
__slots__ = ('version', 'data', 'x', 'z')

def __init__(self, nbt_data: nbt.NBTFile):
self.version = nbt_data['DataVersion']
self.version = nbt_data['DataVersion'].value
self.data = nbt_data['Level']
self.x = self.data['xPos']
self.z = self.data['zPos']
self.x = self.data['xPos'].value
self.z = self.data['zPos'].value

def get_section(self, y: int) -> nbt.TAG_Compound:
"""
Expand Down Expand Up @@ -133,11 +134,15 @@ def get_block(self, x: int, y: int, z: int, section: Union[int, nbt.TAG_Compound
# that holds the blocks index on the palette list
states = section['BlockStates'].value

# in 20w17a and newer blocks cannot occupy more than one element on the BlockStates array
stretches = self.version < _VERSION_20w17a
# stretches = True

# get location in the BlockStates array via the index
if self.version.value >= _Version_20w_17a:
state = index // (64 // bits)
else:
if stretches:
state = index * bits // 64
else:
state = index // (64 // bits)

# makes sure the number is unsigned
# by adding 2^64
Expand All @@ -146,22 +151,19 @@ def get_block(self, x: int, y: int, z: int, section: Union[int, nbt.TAG_Compound
if data < 0:
data += 2**64

if self.version.value >= _Version_20w_17a:
shifted_data = data >> (index % (64 // bits))
else:
if stretches:
# shift the number to the right to remove the left over bits
# and shift so the i'th block is the first one
shifted_data = data >> ((bits * index) % 64)
else:
shifted_data = data >> (index % (64 // bits) * bits)

# if there aren't enough bits it means the rest are in the next number
if 64 - ((bits * index) % 64) < bits:
if stretches and 64 - ((bits * index) % 64) < bits:
data = states[state + 1]
if data < 0:
data += 2**64

if self.version.value >= _Version_20w_17a:
shifted_data = data
else:
# get how many bits are from a palette index of the next block
leftover = (bits - ((state + 1) * 64 % bits)) % bits

Expand Down Expand Up @@ -216,21 +218,23 @@ def stream_blocks(self, index: int=0, section: Union[int, nbt.TAG_Compound]=None

bits = max((len(palette) - 1).bit_length(), 4)

if self.version.value >= _Version_20w_17a:
state = index // (64 // bits)
else:
stretches = self.version < _VERSION_20w17a

if stretches:
state = index * bits // 64
else:
state = index // (64 // bits)

data = states[state]
if data < 0:
data += 2**64

bits_mask = 2**bits - 1

if self.version.value >= _Version_20w_17a:
offset = data >> (index % (64 // bits))
if stretches:
offset = (bits * index) % 64
else:
offset = data >> ((bits * index) % 64)
offset = index % (64 // bits) * bits

data_len = 64 - offset
data >>= offset
Expand All @@ -242,14 +246,14 @@ def stream_blocks(self, index: int=0, section: Union[int, nbt.TAG_Compound]=None
if new_data < 0:
new_data += 2**64

if self.version.value >= _Version_20w_17a:
data = new_data
data_len = 64
else:
if stretches:
leftover = data_len
data_len += 64

data = bin_append(new_data, data, leftover)
else:
data = new_data
data_len = 64

palette_id = data & bits_mask
yield Block.from_palette(palette[palette_id])
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name='anvil-parser',
version='0.6.1',
version='0.6.2',
author='mat',
description='A Minecraft anvil file format parser',
long_description=long_description,
Expand Down

0 comments on commit 24b45b5

Please sign in to comment.