How can read Minecraft .mca files so that in python I can extract individual blocks?

Question:

I can’t find a way of reading the Minecraft world files in a way that i could use in python

I’ve looked around the internet but can find no tutorials and only a few libraries that claim that they can do this but never actually work

from nbt import *
nbtfile = nbt.NBTFile("r.0.0.mca",'rb')

I expected this to work but instead I got errors about the file not being compressed or something of the sort

Full error:

Traceback (most recent call last):
  File "C:UsersroberDesktopMinePyMinecraftWorldReader.py", line 2, in <module>
    nbtfile = nbt.NBTFile("r.0.0.mca",'rb')
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libsite-packagesnbtnbt.py", line 628, in __init__
    self.parse_file()
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libsite-packagesnbtnbt.py", line 652, in parse_file
    type = TAG_Byte(buffer=self.file)
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libsite-packagesnbtnbt.py", line 99, in __init__
    self._parse_buffer(buffer)
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libsite-packagesnbtnbt.py", line 105, in _parse_buffer
    self.value = self.fmt.unpack(buffer.read(self.fmt.size))[0]
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libgzip.py", line 276, in read
    return self._buffer.read(size)
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32lib_compression.py", line 68, in readinto
    data = self.read(len(byte_view))
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libgzip.py", line 463, in read
    if not self._read_gzip_header():
  File "C:UsersroberAppDataLocalProgramsPythonPython36-32libgzip.py", line 411, in _read_gzip_header
    raise OSError('Not a gzipped file (%r)' % magic)
OSError: Not a gzipped file (b'x00x00')
Asked By: Robert Lucas

||

Answers:

Use anvil parser. (Install with pip install anvil-parser)

Reading

import anvil

region = anvil.Region.from_file('r.0.0.mca')

# You can also provide the region file name instead of the object
chunk = anvil.Chunk.from_region(region, 0, 0)

# If `section` is not provided, will get it from the y coords
# and assume it's global
block = chunk.get_block(0, 0, 0)

print(block) # <Block(minecraft:air)>
print(block.id) # air
print(block.properties) # {}

https://pypi.org/project/anvil-parser/

Answered By: Leo Minton

According to this page, the .mca files is not totally kind of of NBT file. It begins with an 8KiB header which includes the offsets of chunks in the region file itself and the timestamps for the last updates of those chunks.
I recommend you to see the offical announcement and this page for more information.

Answered By: CoderCharlie
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.