diff --git a/region-fixer.py b/region-fixer.py index 911f87d..e180e11 100644 --- a/region-fixer.py +++ b/region-fixer.py @@ -225,6 +225,7 @@ def main(): scan_world(world_obj, options) + print world_obj.generate_report(standalone = True) corrupted, wrong_located, entities_prob, shared_prob, total_chunks, too_small_region, unreadable_region, total_regions = world_obj.generate_report(standalone = False) print @@ -281,7 +282,7 @@ def main(): # print a summary for this world if options.summary: summary_text += world_obj.summary() - + world_obj.replace_leaves() # verbose log text if options.summary == '-': print "\nPrinting log:\n" diff --git a/scan.py b/scan.py index 39eba70..0931c4a 100644 --- a/scan.py +++ b/scan.py @@ -661,6 +661,8 @@ def scan_region_file(scanned_regionfile_obj, options): block_aggregation = [0] * 4096 containers = [] r = scanned_regionfile_obj + + # counters of problems chunk_count = 0 corrupted = 0 @@ -698,6 +700,8 @@ def scan_region_file(scanned_regionfile_obj, options): # start the actual chunk scanning g_coords = r.get_global_chunk_coords(x, z) chunk, c = scan_chunk(region_file, (x,z), g_coords, o, block_aggregation, containers) + + if c != None: # chunk not created r.chunks[(x,z)] = c chunk_count += 1 @@ -790,6 +794,7 @@ def scan_chunk(region_file, coords, global_coords, options, block_aggregation, c try: chunk_block_aggregation = [0] * 4096 chunk = region_file.get_chunk(*coords) + data_coords = world.get_chunk_data_coords(chunk) num_entities = len(chunk["Level"]["Entities"]) if data_coords != global_coords: @@ -806,6 +811,8 @@ def scan_chunk(region_file, coords, global_coords, options, block_aggregation, c scan_time = time.time() # Grab our chunk info real_chunk = nbt_chunk.Chunk(chunk) + + # Let's just parse NBT chunk sections to get accurate block counts chunk_sections = real_chunk.chunk_data['Sections'] parsed_sections = [0] * 16 diff --git a/world.py b/world.py index 735bb63..879d515 100644 --- a/world.py +++ b/world.py @@ -22,6 +22,7 @@ # import nbt.region as region +import nbt.chunk as nbt_chunk import nbt.nbt as nbt from util import table @@ -31,6 +32,7 @@ from shutil import copy import time +import math # Constants: # Used to mark the status of a chunks: @@ -178,6 +180,8 @@ def __init__(self, filename, corrupted = 0, wrong = 0, entities_prob = 0, shared self.block_aggregation = [0 for i in xrange(4096)] self.containers = [] + + def __str__(self): text = "Path: {0}".format(self.path) scanned = False @@ -328,6 +332,55 @@ def remove_chunk_entities(self, x, z): return counter + + def replace_leaves(self): + chunks = self.list_chunks() + for c in chunks: + global_coords = c[0] + status_tuple = c[1] + local_coords = _get_local_chunk_coords(*global_coords) + self.replace_chunk_leaves(*local_coords) + + def replace_chunk_leaves(self, x, z): + region_file = region.RegionFile(self.path) + chunk = region_file.get_chunk(x,z) + + sections = chunk['Level']['Sections'] + + i = 0 + for s in sections: + blocks = s['Blocks'] + data = s['Data'] + + ii = -1 + for b in blocks: + ii += 1 + if(b != 18 and b != 161): + continue + + dataPos = int(math.floor(ii/2)) + dataVal = data[dataPos] + + + if(ii % 2 == 0): + # first 4 bits + if (dataVal & 64) != 0: + dataVal -= 64 + + else: + # last 4 bits + if (dataVal & 4) != 0: + dataVal -= 4 + + + chunk['Level']['Sections'][i]['Data'][dataPos] = dataVal + i += 1 + + # for block in cchunk.blocks.blocksList: + region_file.write_chunk(x, z, chunk) + + + def rescan_entities(self, options): """ Updates the status of all the chunks in the region file when the the option entity limit is changed. """ @@ -735,6 +788,8 @@ def replace_problematic_chunks(self, backup_worlds, problem, options): b_regionset = temp_regionset break + + # this don't need to be aware of region status, it just # iterates the list returned by list_chunks() bad_chunks = regionset.list_chunks(problem) @@ -870,6 +925,11 @@ def rescan_entities(self, options): option entity limit is changed. """ for regionset in self.regionsets: regionset.rescan_entities(options) + + def replace_leaves(self): + for regionset in self.regionsets: + for region in regionset.list_regions(): + region.replace_leaves() def generate_report(self, standalone):