Skip to content

Instantly share code, notes, and snippets.

@gamikun
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamikun/67fcc3cea93f2ea84694 to your computer and use it in GitHub Desktop.
Save gamikun/67fcc3cea93f2ea84694 to your computer and use it in GitHub Desktop.
Simple Minecraft NBT parser for Python
class NBTParser(object):
END = 0
BYTE = 1
COMPOUND = 10
SHORT = 2
INT = 3
LONG = 4
FLOAT = 5
DOUBLE = 6
BYTE_ARRAY = 7
STRING = 8
LIST = 9
INT_ARRAY = 11
offset = 0
def __init__(self, data=None):
self.data = data
self.length = len(data)
def parse_tag(self, fixed_id=None, only_payload=False, level=''):
tag = NBTTag()
tag.id = self.read_byte() \
if fixed_id is None else fixed_id
print(level + str(tag.id), end="\n" if tag.id == self.END else '')
sys.stdout.flush()
if tag.id == self.END:
return tag
if not only_payload:
tag_length = self.read_short()
tag.name = self.read(tag_length) if tag_length > 0 else ''
else:
tag.name = ''
print(' - %s (%s)' % (tag.name, hexlify(tag.name)))
if tag.id == self.INT:
return tag.set_value(self.read_int())
if tag.id == self.SHORT:
return tag.set_value(self.read_short())
if tag.id == self.LONG:
tag.value = self.read_long()
if tag.id == self.FLOAT:
tag.value = self.read_float()
if tag.id == self.DOUBLE:
tag.value = self.read_double()
if tag.id == self.BYTE:
tag.value = self.read_byte()
if tag.id == self.INT_ARRAY:
self.values = []
array_size = self.read_int()
for i in range(array_size):
self.values.append(self.read_int())
if tag.id == self.COMPOUND:
tag.nodes = {}
while 1:
node = self.parse_tag(level=level + ' ')
if node.id == self.END:
return tag
tag.nodes[node.name] = node
if tag.id == self.LIST:
list_tag_id = self.read_byte()
list_size = self.read_int()
tag.nodes = []
for i in range(list_size):
node = self.parse_tag(
fixed_id=list_tag_id,
only_payload=True,
level=level + ' ')
tag.nodes.append(node)
if tag.id == self.BYTE_ARRAY:
int_size = self.read_int()
tag.value = self.read(int_size)
if tag.id == self.STRING:
short_size = self.read_short()
tag.value = self.read(short_size)
return tag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment