Skip to content

Instantly share code, notes, and snippets.

@kurokikaze
Created November 18, 2010 17:29
Show Gist options
  • Save kurokikaze/705315 to your computer and use it in GitHub Desktop.
Save kurokikaze/705315 to your computer and use it in GitHub Desktop.
Minecraft chunk file reader
from struct import unpack
tag_types = { 0 : 'End',
1 : 'Byte',
2 : 'Short',
3 : 'Int',
4 : 'Long',
5 : 'Float',
6 : 'Double',
7 : 'Byte array',
8 : 'String',
9 : 'List',
10 : 'Compound'}
# Read number and type of list items and print them
def read_list_payload(chunk):
list_item_type = ord(chunk.read(1))
list_length = unpack('>l', chunk.read(4))[0]
print "%d items of type %s" % (list_length, tag_types[list_item_type])
def read_byte(chunk):
return ord(chunk.read(1))
def read_short(chunk):
return unpack('>h', chunk.read(2))[0]
def read_int(chunk):
return unpack('>l', chunk.read(4))[0]
def read_long(chunk):
return unpack('>q', chunk.read(8))[0]
def read_byte_array(chunk):
length = read_int(chunk)
print "Array length: %d" % length
payload = chunk.read(length)
return payload
def read_compound(chunk):
payload = []
tag = read_tag(chunk)
payload.append(tag)
tag_type = tag[0]
while (tag_type > 0):
tag = read_tag(chunk)
payload.append(tag)
tag_type = tag[0]
print "Read %d elements in compound" % len(payload)
return payload
def read_string(chunk):
str_length = unpack('>h', chunk.read(2))[0]
if (str_length > 0):
str = chunk.read(str_length)
#print "Name: %s" % name
else:
str = None
return str
def read_tag(chunk):
type = ord(chunk.read(1)) # Chunk starts with "10" byte
print "Found tag type: %s" % (tag_types[type], )
if (type > 0):
name = read_string(chunk)
if (name != None):
print "Name: %s" % name
else:
name = ''
payload = None
# Read payload of each tag. "0" tag has no payload
if (type == 1):
payload = read_byte(chunk)
elif (type == 2):
payload = read_short(chunk)
elif (type == 3):
payload = read_int(chunk)
elif (type == 4):
payload = read_long(chunk)
elif (type == 5): # no separate float for now
payload = read_long(chunk)
elif (type == 6): # no separate double for now
payload = read_long(chunk)
elif (type == 7):
payload = read_byte_array(chunk)
elif (type == 8):
payload = read_string(chunk)
elif (type == 9):
payload = read_list_payload(chunk)
elif (type == 10):
payload = read_compound(chunk)
return (type, name, payload)
chunk = open('c.-d.18', 'r')
output = read_tag(chunk)
@kurokikaze
Copy link
Author

Массив tag_types по большому счёту не нужен, я использовал его для вывода типов прочитанных тегов

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment