diff --git a/overviewer.py b/overviewer.py index 5cf28b2..61a1d91 100755 --- a/overviewer.py +++ b/overviewer.py @@ -41,6 +41,7 @@ from overviewer_core import optimizeimages, world from overviewer_core import configParser, tileset, assetmanager, dispatcher from overviewer_core import cache from overviewer_core import observer +from overviewer_core.nbt import CorruptNBTError helptext = """ %prog [--rendermodes=...] [options] @@ -466,7 +467,12 @@ dir but you forgot to put quotes around the directory, since it contains spaces. try: w = worldcache[render['world']] except KeyError: - w = world.World(render['world']) + try: + w = world.World(render['world']) + except CorruptNBTError, e: + logging.error("Failed to open world %r", render['world']) + raise e + worldcache[render['world']] = w # find or create the textures object @@ -595,10 +601,16 @@ def list_worlds(): continue except ValueError: pass - timestamp = time.strftime("%Y-%m-%d %H:%M", + if info['LastPlayed'] > 0: + timestamp = time.strftime("%Y-%m-%d %H:%M", time.localtime(info['LastPlayed'] / 1000)) - playtime = info['Time'] / 20 - playstamp = '%d:%02d' % (playtime / 3600, playtime / 60 % 60) + else: + timestamp = "" + if info['Time'] > 0: + playtime = info['Time'] / 20 + playstamp = '%d:%02d' % (playtime / 3600, playtime / 60 % 60) + else: + playstamp = "" path = info['path'] print(formatString % (name, playstamp, timestamp, path)) diff --git a/overviewer_core/nbt.py b/overviewer_core/nbt.py index d892226..4e21464 100644 --- a/overviewer_core/nbt.py +++ b/overviewer_core/nbt.py @@ -189,7 +189,7 @@ class NBTFileReader(object): payload = self._read_tag_compound() return (name, payload) - except (struct.error, ValueError), e: + except (struct.error, ValueError, TypeError), e: raise CorruptNBTError("could not parse nbt: %s" % (str(e),)) # For reference, the MCR format is outlined at diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 47528fd..d7b01c0 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -792,9 +792,16 @@ def get_worlds(): for dir in os.listdir("."): world_dat = os.path.join(dir, "level.dat") if not os.path.exists(world_dat): continue - info = nbt.load(world_dat)[1] - info['Data']['path'] = os.path.join(".", dir).decode(loc) - if 'LevelName' in info['Data'].keys(): - ret[info['Data']['LevelName']] = info['Data'] + world_path = os.path.join(".", dir) + try: + info = nbt.load(world_dat)[1] + info['Data']['path'] = world_path.decode(loc) + if 'LevelName' in info['Data'].keys(): + ret[info['Data']['LevelName']] = info['Data'] + except nbt.CorruptNBTError: + ret[os.path.basename(world_path).decode(loc) + " (corrupt)"] = {'path': world_path.decode(loc), + 'LastPlayed': 0, + 'Time': 0, + 'IsCorrupt': True} return ret