Last active
October 17, 2020 04:53
-
-
Save wgaylord/ff7ff3d3f328f553586c10109c17ff1d to your computer and use it in GitHub Desktop.
My hack to get chunks in 1.16.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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