From 5ae361824bf6ce00360b30dd9277a92a33005945 Mon Sep 17 00:00:00 2001 From: Alex Headley Date: Sat, 19 Mar 2011 17:45:20 -0400 Subject: [PATCH] cleaned up contrib/validateRegionFile script --- contrib/validateRegionFile.py | 201 +++++++++++++++++----------------- 1 file changed, 100 insertions(+), 101 deletions(-) diff --git a/contrib/validateRegionFile.py b/contrib/validateRegionFile.py index 34ec1fe..7dd2763 100644 --- a/contrib/validateRegionFile.py +++ b/contrib/validateRegionFile.py @@ -1,106 +1,105 @@ -#!/usr/bin/python +#!/usr/bin/env python -usage = "python contrib/%prog [OPTIONS] ()*" - -description = """ -This script will valide a minecraft region file for errors -""" - -from optparse import OptionParser -import sys -import re import os.path -import logging +import sys +overviewer_dir = os.path.split(os.path.split(os.path.abspath(__file__))[0])[0] +sys.path.insert(0, overviewer_dir) +import nbt - - -def main(): - # sys.path wrangling, so we can access Overviewer code - overviewer_dir = os.path.split(os.path.split(os.path.abspath(__file__))[0])[0] - sys.path.insert(0, overviewer_dir) - import nbt - #import chunk - #import quadtree - parser = OptionParser(usage=usage, description=description) - parser.add_option("-r", "--regions", dest="regiondir", help="Use path to the regions instead of a list of files") - parser.add_option("-v", dest="verbose", action="store_true", help="Lists why a chunk in a region failed") - - opt, args = parser.parse_args() - - if opt.regiondir: - if os.path.exists(opt.regiondir): - for dirpath, dirnames, filenames in os.walk(opt.regiondir, 'region'): - if not dirnames and filenames and "DIM-1" not in dirpath: - for f in filenames: - if f.startswith("r.") and f.endswith(".mcr"): - p = f.split(".") - args.append(os.path.join(dirpath, f)) - - if len(args) < 1: - print "You must list at least one region file" - parser.print_help() - sys.exit(1) - - for regionfile in args: - _,shortname = os.path.split(regionfile) - chunk_pass = 0 - chunk_total = 0 - if not os.path.exists(regionfile): - print("File not found: %s"%( regionfile)) - #print("Region:%s Passed %s/%s"%(shortname,chunk_pass,chunk_total)) - continue - try: - mcr = nbt.load_region(regionfile) - except IOError, e: - if opt.verbose: - print("Error opening regionfile. It may be corrupt. %s"%( e)) - continue - if mcr is not None: - try: - chunks = mcr.get_chunk_info(False) - except IOError, e: - if opt.verbose: - print("Error opening regionfile(bad header info). It may be corrupt. %s"%( e)) - chunks = [] - continue - except Exception, e: - if opt.verbose: - print("Error opening regionfile (%s): %s"%( regionfile,e)) - continue - for x, y in chunks: - chunk_total += 1 - try: - chunk_data = mcr.load_chunk(x, y) - except Exception, e: - if opt.verbose: - print("Error reading chunk (%i,%i): %s"%(x,y,e)) - continue - if chunk_data is None: - if opt.verbose: - print("Chunk %s:%s is unexpectedly empty"%(x, y)) - continue - else: - try: - processed = chunk_data.read_all() - if processed == []: - if opt.verbose: - print("Chunk %s:%s is an unexpectedly empty set"%(x, y)) - continue - else: - chunk_pass += 1 - except Exception, e: - if opt.verbose: - print("Error opening chunk (%i, %i) It may be corrupt. %s"%( x, y, e)) - continue - else: - if opt.verbose: - print("Error opening regionfile.") - continue - - print("Region:%s Passed %s/%s"%(shortname,chunk_pass,chunk_total)) -if __name__ == "__main__": +def check_region(region_filename): + chunk_errors = [] + if not os.path.exists(region_filename): + raise Exception('Region file not found: %s' % region_filename) try: - main() - except KeyboardInterrupt: - print "Caught Ctrl-C" + region = nbt.load_region(region_filename) + except IOError, e: + raise Exception('Error loading region (%s): %s' % (region_filename, e)) + try: + chunks = region.get_chunk_info(False) + except IOError, e: + raise Exception('Error reading region header (%s): %s' % (region_filename, e)) + except Exception, e: + raise Exception('Error reading region (%s): %s' % (region_filename, e)) + for x,y in chunks: + try: + check_chunk(region, x, y) + except Exception, e: + chunk_errors.append(e) + return (chunk_errors, len(chunks)) + +def check_chunk(region, x, y): + try: + data = region.load_chunk(x ,y) + except Exception, e: + raise Exception('Error reading chunk (%i, %i): %s' % (x, y, e)) + if data is None: + raise Exception('Chunk (%i, %i) is unexpectedly empty' % (x, y)) + else: + try: + processed_data = data.read_all() + except Exception, e: + raise Exception('Error reading chunk (%i, %i) data: %s' % (x, y, e)) + if processed_data == []: + raise Exception('Chunk (%i, %i) is an unexpectedly empty set' % (x, y)) + +if __name__ == '__main__': + try: + from optparse import OptionParser + + parser = OptionParser(usage='python contrib/%prog [OPTIONS] ', + description='This script will valide a minecraft region file for errors.') + parser.add_option('-v', dest='verbose', action='store_true', help='Print additional information.') + opts, args = parser.parse_args() + region_files = [] + for path in args: + if os.path.isdir(path): + for dirpath, dirnames, filenames in os.walk(path, True): + for filename in filenames: + if filename.startswith('r.') and filename.endswith('.mcr'): + if filename not in region_files: + region_files.append(os.path.join(dirpath, filename)) + elif opts.verbose: + print('Ignoring non-region file: %s' % os.path.join(dirpath, filename)) + elif os.path.isfile(path): + dirpath,filename = os.path.split(path) + if filename.startswith('r.') and filename.endswith('.mcr'): + if path not in region_files: + region_files.append(path) + else: + print('Ignoring non-region file: %s' % path) + else: + if opts.verbose: + print('Ignoring arg: %s' % path) + if len(region_files) < 1: + print 'You must list at least one region file.' + parser.print_help() + sys.exit(1) + else: + overall_chunk_total = 0 + bad_chunk_total = 0 + bad_region_total = 0 + for region_file in region_files: + try: + (chunk_errors, region_chunks) = check_region(region_file) + bad_chunk_total += len(chunk_errors) + overall_chunk_total += region_chunks + except Exception, e: + bad_region_total += 1 + print('FAILED(%s): %s' % (region_file, e)) + else: + if len(chunk_errors) is not 0: + print('WARNING(%s) Chunks: %i/%' % (region_file, region_chunks - len(chunk_errors), region_chunks)) + if opts.verbose: + for error in chunk_errors: + print(error) + elif opts.verbose: + print ('PASSED(%s) Chunks: %i/%i' % (region_file, region_chunks - len(chunk_errors), region_chunks)) + if opts.verbose: + print 'REGIONS: %i/%i' % (len(region_files) - bad_region_total, len(region_files)) + print 'CHUNKS: %i/%i' % (overall_chunk_total - bad_chunk_total, overall_chunk_total) + except KeyboardInterrupt: + sys.exit(1) + except Exception, e: + print('ERROR: %s' % e) +