rendered paste bodyimport 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)