def listDungeons(world, oworld, expand_fill_caves=False): '''Scan a world for dungeons. Try to cache the results and only look at chunks that have changed since the last run.''' global cache_path pm = pmeter.ProgressMeter() # Try to load the cache dungeonCacheOld, mtime = utils.loadDungeonCache(cache_path) dungeonCache = {} # Scan with overviewer regions = oworld.get_regionset(None) count = world.chunkCount cached = 0 notcached = 0 print 'Scanning world for existing dungeons:' print 'cache mtime: %d' % (mtime) pm.init(count, label='') for cx, cz, cmtime in regions.iterate_chunks(): count -= 1 pm.update_left(count) key = '%s,%s' % (cx*16, cz*16) if (cmtime > mtime or key in dungeonCacheOld): notcached += 1 for tileEntity in regions.get_chunk(cx, cz)["TileEntities"]: if ( tileEntity['id'] == 'Sign' and tileEntity['Text1'].startswith('[MCD]') ): key = '%s,%s' % (tileEntity["x"], tileEntity["z"]) dungeonCache[key] = tileEntity if ( tileEntity['id'] == 'Chest' and 'CustomName' in tileEntity and tileEntity['CustomName'] == 'MCDungeon Data Library' ): key = '%s,%s' % (tileEntity["x"], tileEntity["z"]) dungeonCache[key] = tileEntity else: cached += 1 continue pm.set_complete() print ' Cache hit rate: %d/%d (%d%%)' % (cached, world.chunkCount, 100*cached/world.chunkCount) utils.saveDungeonCache(cache_path, dungeonCache) # Process the dungeons dungeons = [] output = '' output += "Known dungeons on this map:\n" output += '+-----------+----------------+---------+-------+----+'\ '-------------------------+\n' output += '| %9s | %14s | %7s | %5s | %2s | %23s |\n' % ( 'Pos', 'Date/Time', 'Ver', 'Size', 'Lv', 'Name' ) output += '+-----------+----------------+---------+-------+----+'\ '-------------------------+\n' for tileEntity in dungeonCache.values(): info = utils.decodeDungeonInfo(tileEntity) (major, minor, patch) = info['version'].split('.') version = float(major+'.'+minor) xsize = info['xsize'] zsize = info['zsize'] levels = info['levels'] offset = 0 if ( expand_fill_caves is True and info['fill_caves'] is True ): offset = 5 dungeons.append((info["position"].x-offset, info["position"].z-offset, xsize+offset, zsize+offset, info, levels, info["position"].x, info["position"].y, info["position"].z, version)) output += '| %9s | %14s | %7s | %5s | %2d | %23s |\n' % ( '%d %d' % (info["position"].x, info["position"].z), time.strftime('%x %H:%M', time.localtime(info['timestamp'])), info['version'], '%dx%d' % (xsize, zsize), levels, info.get('full_name', 'Dungeon')[:23] ) output += '+-----------+----------------+---------+-------+----+'\ '-------------------------+\n' if len(dungeons) > 0: print output else: print 'No dungeons found!' return dungeons
# Populate a list of dungeons to delete. # If --all was specified, populate the delete list will all known dungeons. # Otherwise just validate the -d options. to_delete = [] if args.all is True: for d in dungeons: to_delete.append((d[0], d[1])) else: for d in args.dungeons: if (d[0], d[1]) not in existing: sys.exit('Unable to locate dungeon at %d %d.' % (d[0], d[1])) to_delete.append(d) # Build a list of chunks to delete from the dungeon info. chunks = [] # We need to update the caches for the chunks we are affecting dcache, dmtime = utils.loadDungeonCache(cache_path) ms = mapstore.new(cfg.mapstore, cfg.dir_paintings) for d in to_delete: p = [d[0]/16, d[1]/16] print 'Deleting dungeon at %d %d...' % (d[0], d[1]) dkey = '%s,%s' % (d[0], d[1]) ms.delete_maps(dkey) if dkey in dcache: del dcache[dkey] else: print 'WARN: Dungeon not in dungeon cache! '+dkey xsize = 0 zsize = 0 for e in dungeons: if e[0] == d[0] and e[1] == d[1]: xsize = e[2]