Skip to content

Instantly share code, notes, and snippets.

@wgaylord
Last active October 17, 2020 04:53
Show Gist options
  • Save wgaylord/ff7ff3d3f328f553586c10109c17ff1d to your computer and use it in GitHub Desktop.
Save wgaylord/ff7ff3d3f328f553586c10109c17ff1d to your computer and use it in GitHub Desktop.
My hack to get chunks in 1.16.3
from quarry.types.buffer import Buffer
def unpack_chunk(buff):
x, z, full = buff.unpack('ii?') #Get chunk location and if its full
bitmask = buff.unpack_varint() #Bitmask of the chunk sections
heightmap = buff.unpack_nbt() #Get the heightmap?
biomeLength = 0
if full:
biomeLength = buff.unpack_varint() #Get biome length if full
biomeData = [buff.unpack_varint() for _ in range(biomeLength)] #Get biomes
size = buff.unpack_varint() #Get data section size
chunk_data = []
chunk_buff = Buffer(buff.read(size)) #Use another buffer to make sure all the bytes of size are read because of https://bugs.mojang.com/browse/MC-131684
for u in range(16):
if (bitmask & (2**u)) > 0: #Only unpack chunks that exist
chunk_data.append(unpack_chunk_section(chunk_buff)) #unpack chunk section
else:
chunk_data.append(None)
entities = [buff.unpack_nbt() for _ in range(buff.unpack_varint())] #Unpack entities
return [x,z,full,biomeData,chunk_data,heightmap,entities]
def unpack_chunk_section(buff):
non_air = buff.unpack("H") #Unpack non_air count
bits_per_block = buff.unpack('B') #Unpack bits per block
pallete = None
if bits_per_block <= 8: #check if pallete used
pallete = [buff.unpack_varint() for _ in range(buff.unpack_varint())] #Unpack Pallete
length = buff.unpack_varint() #Unpack Data length
data = [buff.unpack('Q') for _ in range(length)] #unpack Long Longs
section = []
for x in data:
section.extend(unpackLong(x,bits_per_block)) #Get blocks
data = []
if pallete == None:
return [non_air,section] #Return raw data if no pallete
for x in section:
data.append(pallete[x])
return [non_air,data] #Return converted data
def unpackLong(long,bits):
out = []
blockCount = int(64/bits)
offset = blockCount - 1
for x in range(blockCount):
out.append(long >> (bits*offset))
long = long - ((long >> (bits*offset))<< (bits*offset))
offset-=1
return out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment