Created
November 18, 2010 17:29
-
-
Save kurokikaze/705315 to your computer and use it in GitHub Desktop.
Minecraft chunk file reader
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 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Массив tag_types по большому счёту не нужен, я использовал его для вывода типов прочитанных тегов