All pastes #1903205 Raw Edit

Untitled

public python v1 · immutable
#1903205 ·published 2010-07-18 21:33 UTC
rendered paste body
import sysimport gzipimport structstruct_unpack = struct.unpackstruct_pack = struct.packTAG_End = 0TAG_Byte = 1TAG_Short = 2TAG_Int = 3TAG_Long = 4TAG_Float = 5TAG_Double = 6TAG_Byte_Array = 7TAG_String = 8TAG_List = 9TAG_Compound = 10nbt_types = ['TAG_End', 'TAG_Byte', 'TAG_Short', 'TAG_Int', 'TAG_Long', 'TAG_Float',             'TAG_Double', 'TAG_Byte_Array', 'TAG_String', 'TAG_List', 'TAG_Compound']def ReadNBT(stream):    return NBT_Tag().identify(stream)class NBT_Tag(object):    def __init__(self):        self.type = None        self.name = None        self.payload = []        self.payload_type = None    def __repr__(self):        ptype = ''        if self.payload_type:            ptype = ' (%s)' % nbt_types[self.payload_type]        length = ''        if self.type in [TAG_Compound, TAG_List, TAG_Byte_Array]:            length = ' %i items' % len(self.payload)        return '<%s "%s"%s%s>' % (nbt_types[self.type], self.name, ptype, length)    def display(self, children=True, recursive=True, tablevel=0):        text = ('\t' * tablevel) + repr(self) + '\n'        if children:            tabs = '\t' * (tablevel + 1)            if isinstance(self.payload, list):                for child in self.payload:                    if isinstance(child, NBT_Tag):                        if recursive:                            text += child.display(children, recursive, tablevel+1)                        else:                            text += tabs + repr(child) + '\n'                    else:                        text += tabs + repr(child) + '\n'            else:                text += tabs + repr(self.payload) + '\n'        return text    def identify(self, stream):        self.type = ord(stream.read(1))        if self.type:            self.name = self.read_payload(stream, TAG_String)            self.payload = self.read_payload(stream, self.type)        return self    def read_payload(self, stream, type=TAG_End):        if type == TAG_End:            return 0        elif type == TAG_Byte:            return struct_unpack('b', stream.read(1))[0]        elif type == TAG_Short:            return struct_unpack('>h', stream.read(2))[0]        elif type == TAG_Int:            return struct_unpack('>i', stream.read(4))[0]        elif type == TAG_Long:            return struct_unpack('>q', stream.read(8))[0]        elif type == TAG_Float:            return struct_unpack('>f', stream.read(4))[0]        elif type == TAG_Double:            return struct_unpack('>d', stream.read(8))[0]        elif type == TAG_Byte_Array:            length = struct_unpack('>i', stream.read(4))[0] # TAG_Int            array = []            for x in stream.read(length):                array.append(struct_unpack('b', x)[0]) # TAG_Byte            return array        elif type == TAG_String:            length = struct_unpack('>h', stream.read(2))[0] # TAG_Short            return stream.read(length)        elif type == TAG_List:            tag_type = struct_unpack('b', stream.read(1))[0] # TAG_Byte            length = struct_unpack('>i', stream.read(4))[0] # TAG_Int            self.payload_type = tag_type            array = []            for x in xrange(length):                array.append(self.read_payload(stream, tag_type))            return array        elif type == TAG_Compound:            payloads = []            while True:                try:                    tag = NBT_Tag().identify(stream)                except TypeError:                    break                if tag.type == TAG_End:                    break                payloads.append(tag)            return payloads        return None    def write(self):        data = chr(self.type) + struct_pack('>h', len(self.name)) + self.name        payload = self.write_payload(self.type, self.payload)        if payload != None:            data += payload        return data    def write_payload(self, type, payload):        if payload == None:            return        if type == TAG_End:            return 0        elif type == TAG_Byte:            return struct_pack('b', payload)        elif type == TAG_Short:            return struct_pack('>h', payload)        elif type == TAG_Int:            return struct_pack('>i', payload)        elif type == TAG_Long:            return struct_pack('>q', payload)        elif type == TAG_Float:            return struct_pack('>f', payload)        elif type == TAG_Double:            return struct_pack('>d', payload)        elif type == TAG_Byte_Array:            length = struct_pack('>i', len(payload)) # TAG_Int            array = length            for x in payload:                array = array + struct_pack('b', x) # TAG_Byte            return array        elif type == TAG_String:            length = struct_pack('>h', len(payload)) # TAG_Short            return length + payload        elif type == TAG_List:            tag_type = struct_pack('b', self.payload_type) # TAG_Byte            length = struct_pack('>i', len(payload)) # TAG_Int            array = '%s%s' % (tag_type, length)            for x in payload:                array = array + self.write_payload(self.payload_type, x)            return array        elif type == TAG_Compound:            data = ''            for child in payload:                if isinstance(child, NBT_Tag):                    data += child.write()                else:                    print child, child.type            return data + chr(0) # TAG_Endif __name__ == '__main__':    import time    import os    import win32gui    import win32con    def getMinecraftWindow():        def windowTest(hWnd, result):            if win32gui.GetWindowText(hWnd).startswith('Minecraft'):                result.append(hWnd)        result = []        win32gui.EnumWindows(windowTest, result)        return result[0]    hWnd = getMinecraftWindow()    file_path = r'C:\Documents and Settings\Crashed\Application Data\.minecraft\saves\World5\level.dat'    # http://stackoverflow.com/questions/626796/how-do-i-find-the-windows-common-application-data-folder-using-python    from win32com.shell import shellcon, shell                appdata = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)    file_path = os.path.join(appdata, '.minecraft', 'saves')    files = os.listdir(file_path)    print str('\n'.join([('%i: %s' % (x,i)) for x,i in enumerate(files)]))    level = raw_input('Select a save: ')    try:        file_path = os.path.join(file_path, files[int(level)], 'level.dat')    except Exception, e:        print e        sys.exit(1)    last_change = -1    directions = {0: 'NORTH', 360: 'NORTH', 45: 'NORTHEAST', 90: 'EAST', 135: 'SOUTHEAST', 180: 'SOUTH', 225: 'SOUTHWEST', 270: 'WEST', 315: 'NORTHWEST'}    while True:        try:            change = os.stat(file_path).st_mtime            if change != last_change:                last_change = change                root = ReadNBT(gzip.open(file_path, 'rb'))                data = root.payload[0]                player = [x for x in data.payload if isinstance(x, NBT_Tag) and x.name == 'Player'][0]                position = [x for x in player.payload if isinstance(x, NBT_Tag) and x.name == 'Pos'][0]                motion = [x for x in player.payload if isinstance(x, NBT_Tag) and x.name == 'Motion'][0]                rotation = [x for x in player.payload if isinstance(x, NBT_Tag) and x.name == 'Rotation'][0]                y_rotation = rotation.payload[0]                while y_rotation >= 360:                    y_rotation -= 360                while y_rotation < 0:                    y_rotation += 360                y_rotation = directions[round(y_rotation / 45.0) * 45.0]                pos = '%i,%i,%i' % (position.payload[0], position.payload[1], position.payload[2])                mot = '%.6f,%.6f,%.6f' % (motion.payload[0], motion.payload[1], motion.payload[2])                win32gui.SetWindowText(hWnd, 'Minecraft - position: %s | velocity: %s | direction: %s' % (pos, mot, y_rotation))        except WindowsError:            pass        except IOError:            pass        time.sleep(0.02)