def testErrors(self): """ attempt to name elements of a TAG_List named list elements are not allowed by the NBT spec, so we must discard any names when writing a list. """ level = self.testCreate() level["Map"]["Spawn"][0].name = "Torg Potter" data = level.save() newlevel = nbt.load(buf=data) n = newlevel["Map"]["Spawn"][0].name if n: print "Named list element failed: %s" % n # attempt to delete non-existent TAG_Compound elements # this generates a KeyError like a python dict does. level = self.testCreate() try: del level["DEADBEEF"] except KeyError: pass else: assert False
def load_migration_data(): print("Loading migration data...") data = nbt.load(RAW_DATA_FILE) fromItems = {} for (key, val) in data.items(): fromItems[key] = val return fromItems
def testErrors(self): """ attempt to name elements of a TAG_List named list elements are not allowed by the NBT spec, so we must discard any names when writing a list. """ level = self.testCreate() level["Map"]["Spawn"][0].name = "Torg Potter" data = level.save() newlevel = nbt.load(buf=data) n = newlevel["Map"]["Spawn"][0].name if n: print("Named list element failed: %s" % n) # attempt to delete non-existent TAG_Compound elements # this generates a KeyError like a python dict does. level = self.testCreate() try: del level["DEADBEEF"] except KeyError: pass else: assert False
def load(self): ''' Loads the 'mcedit_waypoints.dat' file from the world directory if it exists. If it doesn't exist, it sets the 'Empty' waypoint ''' if self.editor.level is None: return if not os.path.exists( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.build() else: try: self.nbt_waypoints = nbt.load( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) except nbt.NBTFormatError: shutil.move( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"), os.path.join(self.worldDirectory, u"mcedit_waypoints_backup.dat")) log.warning("Waypoint data file corrupted, ignoring...") finally: self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0, 0, 0, 0, 0, 0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"]) del self.nbt_waypoints["LastPosition"]
def loadFile(fName): if not fName: fName = mcplatform.askOpenFile(title=_("Select a NBT (.dat) file..."), suffixes=['dat',]) if fName: if not os.path.isfile(fName): alert("The selected object is not a file.\nCan't load it.") return dontSaveRootTag = False nbtObject = load(fName) if fName.endswith('.schematic'): nbtObject = TAG_Compound(name='Data', value=nbtObject) dontSaveRootTag = True dataKeyName = 'Data' elif nbtObject.get('Data', None): dataKeyName = 'Data' elif nbtObject.get('data', None): dataKeyName = 'data' else: nbtObject.name = 'Data' dataKeyName = 'Data' dontSaveRootTag = True nbtObject = TAG_Compound([nbtObject,]) # dontSaveRootTag = not fName.endswith('.schematic') return nbtObject, dataKeyName, dontSaveRootTag, fName return [None,] * 4
def loadFile(self, fName=None): if not fName: fName = mcplatform.askOpenFile(title="Select a NBT (.dat) file...", suffixes=[ 'dat', ]) if fName: if not os.path.isfile(fName): alert("The selected object is not a file.\nCan't load it.") return dontSaveRootTag = False nbtObject = load(fName) dataKeyName = None if nbtObject.get('Data', None): dataKeyName = 'Data' elif nbtObject.get('data', None): dataKeyName = 'data' else: nbtObject.name = 'Data' dataKeyName = 'Data' dontSaveRootTag = True nbtObject = TAG_Compound([ nbtObject, ]) self.editor.currentTool = self self.showPanel(fName, nbtObject, dontSaveRootTag, dataKeyName) self.optionsPanel.dismiss()
def testBigEndianIntHeightMap(self): """ Test modifying, saving, and loading the new TAG_Int_Array heightmap added with the Anvil format. """ chunk = nbt.load("testfiles/AnvilChunk.dat") hm = chunk["Level"]["HeightMap"] hm.value[2] = 500 oldhm = numpy.array(hm.value) filename = mktemp("ChangedChunk") chunk.save(filename) changedChunk = nbt.load(filename) os.unlink(filename) eq = (changedChunk["Level"]["HeightMap"].value == oldhm) assert eq.all()
def testSpeed(): d = join("testfiles", "TileTicks_chunks") files = [join(d, f) for f in os.listdir(d)] startTime = time.time() for f in files[:40]: n = nbt.load(f) duration = time.time() - startTime assert duration < 1.0 # Will fail when not using _nbt.pyx
def __init__(self, mapstore, dir_paintings='paintings', mapcolor=11141120, paintingcolor=14079638): self.mapstore = os.path.join(mapstore, 'data') self.mapcolor = mapcolor self.paintingcolor = paintingcolor # Load the idcounts.dat NBT if it exists, otherwise make # a new one. try: self.idcounts = nbt.load( os.path.join( self.mapstore, 'idcounts.dat')) except: print 'No idcounts.dat file found. Creating a new one...' self.idcounts = nbt.TAG_Compound() # Load the mcdungeon map ID usage cache if (os.path.isfile(os.path.join(self.mapstore, 'mcdungeon_maps'))): try: with open(os.path.join(self.mapstore, 'mcdungeon_maps'), 'rb') as FILE: self.mapcache = cPickle.load(FILE) except Exception as e: print e print "Failed to read the mcdungeon maps cache file." print "The file tracking MCDungeon map usage may be corrupt." print "You can try deleting or moving this file to recover:" print os.path.join(self.mapstore, 'mcdungeon_maps') sys.exit(1) else: print 'Mapstore cache not found. Creating new one...' self.mapcache = {'used': {}, 'available': set([])} # Generate map hash table self.maphash = {} for file in os.listdir(self.mapstore): if (str(file.lower()).endswith(".dat") and str(file.lower()).startswith("map_")): # Gen hash and extract map ID hash = hashlib.md5( open( os.path.join( self.mapstore, file), 'r').read()).digest() self.maphash[hash] = int(file[4:-4]) # Store paintings path if os.path.isdir(os.path.join(sys.path[0], dir_paintings)): self.painting_path = os.path.join(sys.path[0], dir_paintings) elif os.path.isdir(dir_paintings): self.painting_path = dir_paintings else: sys.exit("Error: Could not find the paintings folder!")
def loadFile(fName): if not fName: fName = mcplatform.askOpenFile(title=_("Select a NBT (.dat) file..."), suffixes=[ 'dat', ]) if fName: if not os.path.isfile(fName): alert("The selected object is not a file.\nCan't load it.") return savePolicy = 0 data = open(fName).read() if struct.Struct('<i').unpack(data[:4])[0] in (3, 4): if struct.Struct('<i').unpack(data[4:8])[0] != len(data[8:]): raise NBTFormatError() with littleEndianNBT(): nbtObject = load(buf=data[8:]) savePolicy = 1 elif struct.Struct('<i').unpack(data[:4])[0] in (1, 2): alert(_("Old PE level.dat, unsupported at the moment.")) else: nbtObject = load(buf=data) if fName.endswith('.schematic'): nbtObject = TAG_Compound(name='Data', value=nbtObject) savePolicy = -1 dataKeyName = 'Data' elif nbtObject.get('Data', None): dataKeyName = 'Data' elif nbtObject.get('data', None): dataKeyName = 'data' else: nbtObject.name = 'Data' dataKeyName = 'Data' if savePolicy == 0: savePolicy = -1 nbtObject = TAG_Compound([ nbtObject, ]) return nbtObject, dataKeyName, savePolicy, fName return [None] * 4
def __init__(self, mapstore, dir_paintings='paintings', mapcolor=11141120, paintingcolor=14079638): self.mapstore = os.path.join(mapstore, 'data') self.mapcolor = mapcolor self.paintingcolor = paintingcolor # Load the idcounts.dat NBT if it exists, otherwise make # a new one. try: self.idcounts = nbt.load( os.path.join(self.mapstore, 'idcounts.dat')) except: print 'No idcounts.dat file found. Creating a new one...' self.idcounts = nbt.TAG_Compound() # Load the mcdungeon map ID usage cache if (os.path.isfile(os.path.join(self.mapstore, 'mcdungeon_maps'))): try: with open(os.path.join(self.mapstore, 'mcdungeon_maps'), 'rb') as FILE: self.mapcache = cPickle.load(FILE) except Exception as e: print e print "Failed to read the mcdungeon maps cache file." print "The file tracking MCDungeon map usage may be corrupt." print "You can try deleting or moving this file to recover:" print os.path.join(self.mapstore, 'mcdungeon_maps') sys.exit(1) else: print 'Mapstore cache not found. Creating new one...' self.mapcache = {'used': {}, 'available': set([])} # Generate map hash table self.maphash = {} for file in os.listdir(self.mapstore): if (str(file.lower()).endswith(".dat") and str(file.lower()).startswith("map_")): # Gen hash and extract map ID hash = hashlib.md5( open(os.path.join(self.mapstore, file), 'r').read()).digest() self.maphash[hash] = int(file[4:-4]) # Store paintings path if os.path.isdir(os.path.join(sys.path[0], dir_paintings)): self.painting_path = os.path.join(sys.path[0], dir_paintings) elif os.path.isdir(dir_paintings): self.painting_path = dir_paintings else: sys.exit("Error: Could not find the paintings folder!")
def testLoad(): "Load an indev level." level = nbt.load("testfiles/hell.mclevel") # The root tag must have a name, and so must any tag within a TAG_Compound print(level.name) # Use the [] operator to look up subtags of a TAG_Compound. print(level["Environment"]["SurroundingGroundHeight"].value) # Numeric, string, and bytearray types have a value that can be accessed and changed. print(level["Map"]["Blocks"].value) return level
def testLoad(): "Load an indev level." level = nbt.load("testfiles/hell.mclevel") # The root tag must have a name, and so must any tag within a TAG_Compound print level.name # Use the [] operator to look up subtags of a TAG_Compound. print level["Environment"]["SurroundingGroundHeight"].value # Numeric, string, and bytearray types have a value that can be accessed and changed. print level["Map"]["Blocks"].value return level
def loadFile(fName): if not fName: fName = mcplatform.askOpenFile(title=_("Select a NBT (.dat) file..."), suffixes=['dat', ]) if fName: if not os.path.isfile(fName): alert("The selected object is not a file.\nCan't load it.") return savePolicy = 0 data = open(fName).read() if struct.Struct('<i').unpack(data[:4])[0] in (3, 4): if struct.Struct('<i').unpack(data[4:8])[0] != len(data[8:]): raise NBTFormatError() with littleEndianNBT(): nbtObject = load(buf=data[8:]) savePolicy = 1 elif struct.Struct('<i').unpack(data[:4])[0] in (1, 2): alert(_("Old PE level.dat, unsupported at the moment.")) else: nbtObject = load(buf=data) if fName.endswith('.schematic'): nbtObject = TAG_Compound(name='Data', value=nbtObject) savePolicy = -1 dataKeyName = 'Data' elif nbtObject.get('Data', None): dataKeyName = 'Data' elif nbtObject.get('data', None): dataKeyName = 'data' else: nbtObject.name = 'Data' dataKeyName = 'Data' if savePolicy == 0: savePolicy = -1 nbtObject = TAG_Compound([nbtObject, ]) return nbtObject, dataKeyName, savePolicy, fName return [None] * 4
def load(self): if self.editor.level is None: return if not os.path.exists(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.nbt_waypoints = nbt.TAG_Compound() self.nbt_waypoints["Waypoints"] = nbt.TAG_List() self.build() else: self.nbt_waypoints = nbt.load(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0,0,0,0,0,0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"])
def load(self): ''' Loads the 'mcedit_waypoints.dat' file from the world directory if it exists. If it doesn't exist, it sets the 'Empty' waypoint ''' if self.editor.level is None: return if not os.path.exists(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.build() else: self.nbt_waypoints = nbt.load(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0,0,0,0,0,0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"]) del self.nbt_waypoints["LastPosition"]
def load(self): ''' Loads the 'mcedit_waypoints.dat' file from the world directory if it exists. If it doesn't exist, it sets the 'Empty' waypoint ''' if self.editor.level is None: return if not os.path.exists( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.build() else: self.nbt_waypoints = nbt.load( os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0, 0, 0, 0, 0, 0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"]) del self.nbt_waypoints["LastPosition"]
def __init__(self, mapstore): self.mapstore = os.path.join(mapstore, 'data') # Load the idcounts.dat NBT if it exists, otherwise make # a new one. try: self.idcounts = nbt.load(os.path.join(self.mapstore, 'idcounts.dat')) except: print 'No idcounts.dat file found. Creating a new one...' self.idcounts = nbt.TAG_Compound() # Load the mcdungeon map ID usage cache if (os.path.isfile(os.path.join(self.mapstore, 'mcdungeon_maps'))): try: with open(os.path.join(self.mapstore, 'mcdungeon_maps'), 'rb') as FILE: self.mapcache = cPickle.load(FILE) except Exception as e: print e sys.exit('Failed to read the mcdungeon maps cache file.') else: print 'Mapstore cache not found. Creating new one...' self.mapcache = {'used': {}, 'available': set([])} # Generate map hash table self.maphash = {} for file in os.listdir(self.mapstore): if (str(file.lower()).endswith(".dat") and str(file.lower()).startswith("map_")): #Gen hash and extract map ID hash = hashlib.md5(open(os.path.join(self.mapstore,file), 'r').read()).digest() self.maphash[hash] = int(file[4:-4]) # Store paintings path if os.path.isdir(os.path.join(sys.path[0],'paintings')): self.painting_path = os.path.join(sys.path[0],'paintings') elif os.path.isdir('paintings'): self.painting_path = 'paintings' else: sys.exit("Error: Could not find the paintings folder!")
def load(self): ''' Loads the 'mcedit_waypoints.dat' file from the world directory if it exists. If it doesn't exist, it sets the 'Empty' waypoint ''' if self.editor.level is None: return if not os.path.exists(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")): self.build() else: try: self.nbt_waypoints = nbt.load(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")) except nbt.NBTFormatError: shutil.move(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"), os.path.join(self.worldDirectory, u"mcedit_waypoints_backup.dat")) log.warning("Waypoint data file corrupted, ignoring...") finally: self.build() if not (len(self.waypoints) > 0): self.waypoints["Empty"] = [0,0,0,0,0,0] if "LastPosition" in self.nbt_waypoints: self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"]) del self.nbt_waypoints["LastPosition"]
def __init__(self, mapstore): self.mapstore = os.path.join(mapstore, 'data') # Load the idcounts.dat NBT if it exists, otherwise make # a new one. try: self.idcounts = nbt.load(os.path.join(self.mapstore, 'idcounts.dat')) except: print 'No idcounts.dat file found. Creating a new one...' self.idcounts = nbt.TAG_Compound() self.idcounts['map'] = nbt.TAG_Short(-1) # Load the mcdungeon map ID usage cache if (os.path.isfile(os.path.join(self.mapstore, 'mcdungeon_maps'))): try: with open(os.path.join(self.mapstore, 'mcdungeon_maps'), 'rb') as FILE: self.mapcache = cPickle.load(FILE) except Exception as e: print e sys.exit('Failed to read the mcdungeon maps cache file.') else: print 'Mapstore cache not found. Creating new one...' self.mapcache = {'used': {}, 'available': set([])}
def LoadNBTFiles(dirname='items'): # Test which path to use. If the path can't be found # just don't load any items. if os.path.isdir(os.path.join(sys.path[0], dirname)): item_path = os.path.join(sys.path[0], dirname) elif os.path.isdir(dirname): item_path = dirname else: print 'Could not find the NBT items folder!' return # Make a list of all the NBT files in the items directory itemlist = [] for file in os.listdir(item_path): if (file.endswith(".nbt")): itemlist.append(file) items_count = 0 for item in itemlist: # SomeItem.nbt would be referenced in loot as file_some_item name = 'file_' + item[:-4].lower() full_path = os.path.join(item_path, item) # Load the nbt file and do some basic validation try: item_nbt = nbt.load(full_path) item_nbt['id'] # Throws an error if not set except: print item + " is an invalid item! Skipping." continue # Skip to next item # If the Count tag exists, use it as our maxstack try: stack = item_nbt['Count'].value except: stack = 1 _items[name] = ItemInfo(name, 0, maxstack=stack, file=full_path) # print _items[name] items_count += 1 print 'Loaded', items_count, 'items from NBT files.'
def LoadNBTFiles(dirname='items'): # Test which path to use. If the path can't be found # just don't load any items. if os.path.isdir(os.path.join(sys.path[0], dirname)): item_path = os.path.join(sys.path[0], dirname) elif os.path.isdir(dirname): item_path = dirname else: print 'Could not find the NBT items folder!' return #Make a list of all the NBT files in the items directory itemlist = [] for file in os.listdir(item_path): if (file.endswith(".nbt")): itemlist.append(file) items_count = 0 for item in itemlist: # SomeItem.nbt would be referenced in loot as file_some_item name = 'file_'+item[:-4].lower() full_path = os.path.join(item_path, item) # Load the nbt file and do some basic validation try: item_nbt = nbt.load(full_path) item_nbt['id'] # Throws an error if not set except: print item + " is an invalid item! Skipping." continue # Skip to next item # If the Count tag exists, use it as our maxstack try: stack = item_nbt['Count'].value except: stack = 1 _items[name] = ItemInfo(name, 0, maxstack=stack, file=full_path) #print _items[name] items_count += 1 print 'Loaded', items_count, 'items from NBT files.'
def on_confirm_overwrite(self, chooser, param=None): """ Our own custom overwrite-confirm dialog """ try: # Try to load it as NBT, and then try to access an Inventory # structure. If we succeed, then we're trying to save-as # an existing Minecraft level.dat, so we should use our custom # dialog to see if the user wants to overwrite fully, or just # do the inventory stuff. Otherwise, just use the default # dialog. nbtdata = nbt.load(self.get_filename()) test = nbtdata['Data'].value['Player'].value['Inventory'].value except Exception: self.overwrite_all = True return gtk.FILE_CHOOSER_CONFIRMATION_CONFIRM dialog = OverwriteConfirmDialog(self, filename=self.get_filename()) result = dialog.run() self.overwrite_all = dialog.is_overwrite_all() dialog.destroy() if result == gtk.RESPONSE_YES: return gtk.FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME else: return gtk.FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN
def testLoadNBTExplorer(): root_tag = nbt.load("testfiles/modified_by_nbtexplorer.dat")
def buildItemTag(self,i): # If it's a binary NBT file, just load it if i.file != '': item_tag = nbt.load(i.file) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag # Otherwise, we will build the compound item_tag = nbt.TAG_Compound() # Standard stuff item_tag['id'] = nbt.TAG_Short(i.id) item_tag['Damage'] = nbt.TAG_Short(i.damage) # Enchantments if len(i.enchantments) > 0: item_tag['tag'] = nbt.TAG_Compound() if (i.flag == 'ENCH_BOOK'): item_tag['tag']['StoredEnchantments'] = nbt.TAG_List() elist = item_tag['tag']['StoredEnchantments'] else: item_tag['tag']['ench'] = nbt.TAG_List() elist = item_tag['tag']['ench'] for e in i.enchantments: e_tag = nbt.TAG_Compound() e_tag['id'] = nbt.TAG_Short(e['id']) e_tag['lvl'] = nbt.TAG_Short(e['lvl']) elist.append(e_tag) # Custom Potion Effects if i.p_effect != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['CustomPotionEffects'] = nbt.TAG_List() elist = item_tag['tag']['CustomPotionEffects'] for e in i.p_effect.split(','): id, amp, dur = e.split('-') e_tag = nbt.TAG_Compound() e_tag['Id'] = nbt.TAG_Byte(id) e_tag['Amplifier'] = nbt.TAG_Byte(amp) e_tag['Duration'] = nbt.TAG_Int(dur) # Flags for hiding potion particles if i.flag == 'HIDE_PARTICLES' or i.flag == 'HIDE_ALL': e_tag['ShowParticles'] = nbt.TAG_Byte(0) elist.append(e_tag) # Flag for hiding additional text if i.flag == 'HIDE_EFFECTS' or i.flag == 'HIDE_ALL': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['HideFlags'] = nbt.TAG_Int(63) # 63 = Hide everything # Naming if i.customname != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Name'] = nbt.TAG_String(i.customname) # Lore Text if i.lore != '' or i.flag == 'FORTUNE': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Lore'] = nbt.TAG_List() if i.flag == 'FORTUNE': item_tag['tag']['display'][ 'Name'] = nbt.TAG_String('Fortune Cookie') i.lore = self.loadrandfortune() loredata = textwrap.wrap(self.ConvertEscapeChars(i.lore), 30) for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(loretext)) else: loredata = i.lore.split(':') for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(self.ConvertEscapeChars(loretext[:50]))) # Dyed if (i.flag == 'DYED'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() if i.flagparam == '': item_tag['tag']['display']['color'] = nbt.TAG_Int( random.randint( 0, 16777215)) else: item_tag['tag']['display']['color'] = nbt.TAG_Int(i.flagparam) # special cases for written books and paintings if (i.flag == 'WRITTEN'): item_tag = self.loadrandbooktext() if (i.flag == 'PAINT'): item_tag = self.loadrandpainting() # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag
def testLoadUncompressed(): root_tag = nbt.load("testfiles/uncompressed.nbt")
def perform(level, box, options): try: level.gamePlatform except: raise Exception( 'This filter requires level.gamePlatform. You will need a version of MCedit that has this' ) global idcount nearest = options[ "Use Nearest-Color Transparency (recommended for lossy image formats):"] tmode = options["Transparency Mode:"] tcolor = options["Transparency Color:"] if tmode == "Use Default Color (#FF00FF)": transparent = (255, 0, 255) elif tmode == "User-Specified Color Below": if tcolor[0] == "#": alphacolor = int(tcolor[1:7], 16) transparent = (alphacolor >> 16, (alphacolor >> 8) & 0xff, alphacolor & 0xff) else: raise Exception( "ERROR! The provided transparency color was formatted incorrectly! Colors must in hexadecimal format, in the form #RRGGBB" ) return else: transparent = None invulnerable = options["Item Frames are invulnerable:"] imgpath = options["Image path:"] facing = options["Item Frames are facing:"] backing = options["Item Frame backing block (replaces air blocks only):"] if backing.ID == 0: raise Exception("ERROR! The backing block CANNOT be air!") return toosmall = options["If selection is too small for image size:"] if level.gamePlatform == 'Java': if level.dimNo: datafolder = level.parentWorld.worldFolder.getFolderPath("data") else: datafolder = level.worldFolder.getFolderPath("data") if not os.path.exists(datafolder): try: os.makedirs(datafolder) except: raise OSError( "ERROR! Data folder does not exist and could not be created. Please create a \"data\" folder at: " + datafolder) return idcountpath = os.path.join(datafolder, "idcounts.dat") if os.path.exists(idcountpath): idcountfile = nbt.load(idcountpath) if "map" in idcountfile: idcount = idcountfile["map"].value else: idcount = 0 idcountfile["map"] = TAG_Short(0) else: idcount = 0 idcountfile = TAG_Compound() idcountfile["map"] = TAG_Short(0) elif level.gamePlatform == 'PE': try: with level.worldFile.world_db() as db: rop = level.worldFile.readOptions idcountfile = loadNBTCompoundList(db.Get(rop, 'MCeditMapIt'))[0] if "map" in idcountfile: idcount = idcountfile["map"].value else: idcount = 0 idcountfile["map"] = TAG_Long(0) except: idcount = 0 idcountfile = TAG_Compound() idcountfile["map"] = TAG_Long(0) if imgpath != "None": if os.path.exists(imgpath): image_path = imgpath else: image_path = mcplatform.askOpenFile(title="Select an Image", schematics=False) else: image_path = mcplatform.askOpenFile(title="Select an Image", schematics=False) if image_path == None: raise Exception("ERROR: No file provided!") return surface = pygame.image.load(image_path) # Adrian Brightmoore # Modification to allow auto-resize to selection dimensions sx, sy, sz = box.size xsize, ysize, zsize = box.size * 128 if toosmall == "Scale to selection": if (facing == "Eastwards (-X to +X)" or facing == "Westwards (+X to -X)"): surface = pygame.transform.smoothscale(surface, (zsize, ysize)) elif (facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)"): surface = pygame.transform.smoothscale(surface, (xsize, ysize)) (height, width) = surface.get_size() # End modification to allow auto-resize to selection dimensions loopx = int(math.ceil(float(width) / 128.0)) loopy = int(math.ceil(float(height) / 128.0)) if level.gamePlatform == 'Java': if (loopx * loopy) + idcount > 32767: raise Exception( "\nERROR! The image size is too large or there are not enough maps left for this world.\n" "Only 32,767 map files are allowed per world, and there are", idcount, "maps in this world.\n" "The image specified requires", (loopx * loopy), "maps.\n") return # elif level.gamePlatform == 'PE': # could do similar code to above but the limit is 2^63 rather than 2^15 so it will never be reached ever chestorframe = "item frames" if ysize < width: if toosmall == "Cancel Image Processing": raise Exception( "\nERROR! The selection height is too small! Your selection should be at least " + str(loopx) + "H in size.\n" "\n" "Cancelled image processing.") else: print "Creating chests instead of Item Frames" chestorframe = "chests" if chestorframe == "item frames" and (facing == "Eastwards (-X to +X)" or facing == "Westwards (+X to -X)"): if zsize < height or sx < 2: if toosmall == "Cancel Image Processing": raise Exception( "\nERROR! The selection size is too small; it selection should be at least\n" "2W x " + str(loopy) + "L x " + str(loopx) + "H in size.\n" "\n" "Cancelled image processing.") else: print "Creating chests instead of Item Frames" chestorframe = "chests" elif chestorframe == "item frames" and (facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)"): if xsize < height or sz < 2: if toosmall == "Cancel Image Processing": raise Exception( "\nERROR! The selection size is too small; it should be at least\n" "" + str(loopy) + "W x 2L x " + str(loopx) + "H in size.\n" "\n" "Cancelled image processing.") else: print "Creating chests instead of Item Frames" chestorframe = "chests" image = numpy.fromstring(pygame.image.tostring(surface, "RGB"), dtype=numpy.uint8).reshape(width, height, 3) progresscount = 1 progressmax = loopx * loopy startid = idcount + 1 def processImageJava(image, loopx, loopy, width, height, cache, transparent, nearest, image_path, progresscount, progressmax): global idcount for lx in xrange(loopx): for ly in xrange(loopy): yield idcount - 1, progressmax, "of image " + image_path progresscount += 1 idcount += 1 converted = numpy.zeros((128, 128), dtype=numpy.uint8) offsetx = lx * 128 offsety = ly * 128 for x in xrange(128): for y in xrange(128): if (offsetx + x) >= width: break elif (offsety + y) >= height: break r, g, b = (image[offsetx + x, offsety + y, 0], image[offsetx + x, offsety + y, 1], image[offsetx + x, offsety + y, 2]) if (r, g, b) in cache: converted[x, y] = cache[(r, g, b)] else: converted[x, y] = FindClosestPaletteIndex( r, g, b, transparent, nearest) if (offsetx + x) >= width: break CreateNewMapFileJava(datafolder, idcount, converted) def processImagePE(image, loopx, loopy, width, height, image_path, progresscount, progressmax): global idcount for lx in xrange(loopx): for ly in xrange(loopy): yield idcount - 1, progressmax, "of image " + image_path progresscount += 1 idcount += 1 print idcount converted = numpy.zeros((65536), dtype=numpy.uint8) offsetx = lx * 128 offsety = ly * 128 for x in xrange(128): for y in xrange(128): if (offsetx + x) >= width: break elif (offsety + y) >= height: break r, g, b = (image[offsetx + x, offsety + y, 0], image[offsetx + x, offsety + y, 1], image[offsetx + x, offsety + y, 2]) converted[4 * (x * 128 + y)] = r converted[4 * (x * 128 + y) + 1] = g converted[4 * (x * 128 + y) + 2] = b converted[4 * (x * 128 + y) + 3] = 255 if (offsetx + x) >= width: break CreateNewMapFilePE(level, idcount, converted) if level.gamePlatform == 'Java': level.showProgress( "Processing image pieces:", processImageJava(image, loopx, loopy, width, height, cache, transparent, nearest, image_path, progresscount, progressmax)) elif level.gamePlatform == 'PE': level.showProgress( "Processing image pieces:", processImagePE(image, loopx, loopy, width, height, image_path, progresscount, progressmax)) print idcount endid = idcount print endid if level.gamePlatform == 'Java': idcountfile["map"] = TAG_Short(idcount) idcountfile.save(idcountpath, compressed=False) elif level.gamePlatform == 'PE': idcountfile["map"] = TAG_Long(idcount) with level.worldFile.world_db() as db: wop = level.worldFile.writeOptions with nbt.littleEndianNBT(): db.Put(wop, 'MCeditMapIt', idcountfile.save(compressed=False)) print "Finished processing image " + image_path + ". Creating " + chestorframe + "..." if chestorframe == "item frames": if level.gamePlatform == 'Java': if facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)": if facing == "Northwards (+Z to -Z)": dir = 0 posIncrement = False else: dir = 2 posIncrement = True else: if facing == "Eastwards (-X to +X)": dir = 3 posIncrement = True else: dir = 1 posIncrement = False if facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)": z = box.minz if posIncrement: z += 1 for y in xrange(box.miny - 1 + loopx, box.miny - 1, -1): for x in xrange(box.minx, box.minx + loopy) if posIncrement else xrange( box.minx - 1 + loopy, box.minx - 1, -1): level.setBlockAt(x, y, z, 0) level.setBlockDataAt(x, y, z, 0) if level.blockAt(x, y, z + (-1 if posIncrement else 1)) == 0: level.setBlockAt(x, y, z + (-1 if posIncrement else 1), backing.ID) level.setBlockDataAt( x, y, z + (-1 if posIncrement else 1), backing.blockData) chunk = level.getChunk(x >> 4, z >> 4) chunk.Entities.append( CreateItemFrameJava(x, y, z, dir, startid, invulnerable)) chunk.dirty = True startid += 1 elif facing == "Eastwards (-X to +X)" or facing == "Westwards (+X to -X)": x = box.minx if posIncrement: x += 1 for y in xrange(box.miny - 1 + loopx, box.miny - 1, -1): for z in xrange(box.minz, box.minz + loopy) if not posIncrement else xrange( box.minz - 1 + loopy, box.minz - 1, -1): level.setBlockAt(x, y, z, 0) level.setBlockDataAt(x, y, z, 0) if level.blockAt(x + (-1 if posIncrement else 1), y, z) == 0: level.setBlockAt(x + (-1 if posIncrement else 1), y, z, backing.ID) level.setBlockDataAt( x + (-1 if posIncrement else 1), y, z, backing.blockData) chunk = level.getChunk(x >> 4, z >> 4) chunk.Entities.append( CreateItemFrameJava(x, y, z, dir, startid, invulnerable)) chunk.dirty = True startid += 1 elif level.gamePlatform == 'PE': if facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)": if facing == "Northwards (+Z to -Z)": dir = 3 posIncrement = False else: dir = 2 posIncrement = True else: if facing == "Eastwards (-X to +X)": dir = 0 posIncrement = True else: dir = 1 posIncrement = False if facing == "Northwards (+Z to -Z)" or facing == "Southwards (-Z to +Z)": z = box.minz if posIncrement: z += 1 for y in xrange(box.miny - 1 + loopx, box.miny - 1, -1): for x in xrange(box.minx, box.minx + loopy) if posIncrement else xrange( box.minx - 1 + loopy, box.minx - 1, -1): level.setBlockAt(x, y, z, 199) level.setBlockDataAt(x, y, z, dir) if level.blockAt(x, y, z + (-1 if posIncrement else 1)) == 0: level.setBlockAt(x, y, z + (-1 if posIncrement else 1), backing.ID) level.setBlockDataAt( x, y, z + (-1 if posIncrement else 1), backing.blockData) chunk = level.getChunk(x >> 4, z >> 4) chunk.TileEntities.append( CreateItemFramePE(x, y, z, startid)) chunk.dirty = True startid += 1 elif facing == "Eastwards (-X to +X)" or facing == "Westwards (+X to -X)": x = box.minx if posIncrement: x += 1 for y in xrange(box.miny - 1 + loopx, box.miny - 1, -1): for z in xrange(box.minz, box.minz + loopy) if not posIncrement else xrange( box.minz - 1 + loopy, box.minz - 1, -1): level.setBlockAt(x, y, z, 199) level.setBlockDataAt(x, y, z, dir) if level.blockAt(x + (-1 if posIncrement else 1), y, z) == 0: level.setBlockAt(x + (-1 if posIncrement else 1), y, z, backing.ID) level.setBlockDataAt( x + (-1 if posIncrement else 1), y, z, backing.blockData) chunk = level.getChunk(x >> 4, z >> 4) chunk.TileEntities.append( CreateItemFramePE(x, y, z, startid)) chunk.dirty = True startid += 1 else: if level.gamePlatform == 'Java': breakout = False entsToAdd = [] for y in xrange(box.miny, box.maxy): for z in xrange(box.minz, box.maxz): for x in xrange(box.minx, box.maxx): newchest = TAG_Compound() newchest["id"] = TAG_String("Chest") newchest["x"] = TAG_Int(x) newchest["y"] = TAG_Int(y) newchest["z"] = TAG_Int(z) newchest["Lock"] = TAG_String() newchest["Items"] = TAG_List() mapitem = TAG_Compound() mapitem["id"] = TAG_String("minecraft:filled_map") mapitem["Count"] = TAG_Byte(1) mapitem["Damage"] = TAG_Short(0) mapitem["Slot"] = TAG_Byte(0) for c in xrange(27): newitem = deepcopy(mapitem) newitem["Slot"] = TAG_Byte(c) newitem["Damage"] = TAG_Short(startid) newchest["Items"].append(newitem) startid += 1 if startid > endid: breakout = True break level.setBlockAt(x, y, z, 54) level.setBlockDataAt(x, y, z, 4) entsToAdd.append( (level.getChunk(x >> 4, z >> 4), deepcopy(newchest))) if breakout: break if breakout: break if breakout: break elif level.gamePlatform == 'PE': breakout = False entsToAdd = [] for y in xrange(box.miny, box.maxy): for z in xrange(box.minz, box.maxz): for x in xrange(box.minx, box.maxx): newchest = TAG_Compound() newchest["id"] = TAG_String("Chest") newchest["x"] = TAG_Int(x) newchest["y"] = TAG_Int(y) newchest["z"] = TAG_Int(z) newchest["Items"] = TAG_List() mapitem = TAG_Compound() mapitem["id"] = TAG_Short(358) mapitem["Count"] = TAG_Byte(16) mapitem["Damage"] = TAG_Short(0) mapitem["tag"] = TAG_Compound() for c in xrange(27): newitem = deepcopy(mapitem) newitem["Slot"] = TAG_Byte(c) newitem["tag"]["map_uuid"] = TAG_Long(startid) newchest["Items"].append(newitem) startid += 1 if startid > endid: breakout = True break level.setBlockAt(x, y, z, 54) level.setBlockDataAt(x, y, z, 4) entsToAdd.append( (level.getChunk(x >> 4, z >> 4), deepcopy(newchest))) if breakout: break if breakout: break if breakout: break for (chunk, entity) in entsToAdd: chunk.TileEntities.append(entity) chunk.dirty = True print "-------------------" print "Filtering complete."
def loadMapTag(level, mapid): mapPath = level.worldFolder.getFilePath("data/map_{}.dat".format(mapid)) if os.path.exists(mapPath): return nbt.load(mapPath) else: return None
def buildItemTag(self, i): # If it's a binary NBT file, just load it if i.file != '': item_tag = nbt.load(i.file) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag # Otherwise, we will build the compound item_tag = nbt.TAG_Compound() # Standard stuff item_tag['id'] = nbt.TAG_Short(i.id) item_tag['Damage'] = nbt.TAG_Short(i.damage) # Enchantments if len(i.enchantments) > 0: item_tag['tag'] = nbt.TAG_Compound() if (i.flag == 'ENCH_BOOK'): item_tag['tag']['StoredEnchantments'] = nbt.TAG_List() elist = item_tag['tag']['StoredEnchantments'] else: item_tag['tag']['ench'] = nbt.TAG_List() elist = item_tag['tag']['ench'] for e in i.enchantments: e_tag = nbt.TAG_Compound() e_tag['id'] = nbt.TAG_Short(e['id']) e_tag['lvl'] = nbt.TAG_Short(e['lvl']) elist.append(e_tag) # Custom Potion Effects if i.p_effect != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['CustomPotionEffects'] = nbt.TAG_List() elist = item_tag['tag']['CustomPotionEffects'] for e in i.p_effect.split(','): id, amp, dur = e.split('-') e_tag = nbt.TAG_Compound() e_tag['Id'] = nbt.TAG_Byte(id) e_tag['Amplifier'] = nbt.TAG_Byte(amp) e_tag['Duration'] = nbt.TAG_Int(dur) # Flags for hiding potion particles if i.flag == 'HIDE_PARTICLES' or i.flag == 'HIDE_ALL': e_tag['ShowParticles'] = nbt.TAG_Byte(0) elist.append(e_tag) # Flag for hiding additional text if i.flag == 'HIDE_EFFECTS' or i.flag == 'HIDE_ALL': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['HideFlags'] = nbt.TAG_Int( 63) # 63 = Hide everything # Naming if i.customname != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Name'] = nbt.TAG_String(i.customname) # Lore Text if i.lore != '' or i.flag == 'FORTUNE': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Lore'] = nbt.TAG_List() if i.flag == 'FORTUNE': item_tag['tag']['display']['Name'] = nbt.TAG_String( 'Fortune Cookie') i.lore = self.loadrandfortune() loredata = textwrap.wrap(self.ConvertEscapeChars(i.lore), 30) for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(loretext)) else: loredata = i.lore.split(':') for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(self.ConvertEscapeChars(loretext[:50]))) # Dyed if (i.flag == 'DYED'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() if i.flagparam == '': item_tag['tag']['display']['color'] = nbt.TAG_Int( random.randint(0, 16777215)) else: item_tag['tag']['display']['color'] = nbt.TAG_Int(i.flagparam) # special cases for written books and paintings if (i.flag == 'WRITTEN'): item_tag = self.loadrandbooktext() if (i.flag == 'PAINT'): item_tag = self.loadrandpainting() # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag
def generate(self, cache_path, version): '''Generate a treasure hunt''' # the treasure hunt name is stored in dungeon_name and is built here # because we don't have a ruins[] section _thnames = ( ('{owners} booty',20), ('{owners} treasure',20), ('{owners} loot', 20), ('{owners} chest', 20), ('{owners} locker', 20), ('{owners} college fund',1) ) # Pick a starting size. self.xsize = 1 self.zsize = 1 self.steps = randint(cfg.min_steps, cfg.max_steps) self.min_distance = cfg.min_distance self.max_distance = cfg.max_distance located = False result = False # Find a landmark, if we can. # Manual landmark if cfg.offset is not '': print 'Treasure hunt step: {1}'.format(self.steps) self.position = str2Vec(cfg.offset) self.position.x = self.position.x & ~15 self.position.z = self.position.z & ~15 # XXX bury the chest below ground self.bury() print "Location set to: ", self.position # Search for a location. else: print "Searching for a suitable location..." located = self.findlocation() if (located is False): print 'Unable to place any more treasure hunts.' else: print 'Treasure hunt steps: {0}'.format(self.steps) print "Location: ", self.position # Generate! if (located is True): # We have a final size, so let's initialize some things. self.heightmap = numpy.zeros(( self.room_size, self.room_size)) # Set the seed if requested. if (self.args.seed is not None): seed(self.args.seed) print 'Seed:', self.args.seed # Now we know the biome, we can setup a name generator self.namegen = namegenerator.namegenerator(None, theme='pirate') print 'Theme:', self.namegen.theme self.owner = self.namegen.genroyalname() print 'Owner:', self.owner print "Location: ", self.position print "Generating landmarks..." self.genlandmarks() # Name this place if self.owner.endswith("s"): owners = self.owner + "'" else: owners = self.owner + "'s" self.dinfo['dungeon_name'] = weighted_choice( _thnames ) self.dungeon_name = self.dinfo['dungeon_name'].format( owner=self.owner, owners=owners) self.dungeon_name = self.dungeon_name[:32] self.dinfo['full_name'] = self.dungeon_name print "Treasure hunt name:", self.dungeon_name self.renderlandmarks() self.placechests() if cfg.th_spawners is True: self.placespawners() self.processBiomes() # Signature self.setblock(Vec(0, 0, 0), materials.Chest, 0, hide=True) self.tile_ents[Vec(0, 0, 0)] = encodeTHuntInfo(self,version) # Add to the dungeon cache. key = '%s,%s' % ( self.position.x, self.position.z, ) # we need the info if making multiple hunts, to avoid # all previous landmarks #self.thunt_cache[key] = self.tile_ents[Vec(0, 0, 0)] self.thunt_cache[key] = True # copy results to the world self.applychanges() # Relight these chunks. if (self.args.write is True and self.args.skiprelight is False): # Super ugly, but does progress bars for lighting. for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) h = RelightHandler() logging.basicConfig(stream=h, level=logging.INFO) self.world.generateLights() h.done() logging.getLogger().level = logging.CRITICAL for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # Saving here allows us to pick up where we left off if we stop. if (self.args.write is True): print "Saving..." self.world.saveInPlace() saveTHuntCache(cache_path, self.thunt_cache) saveChunkCache(cache_path, self.chunk_cache) # make sure commandBlockOutput is false. root_tag = nbt.load(self.world.filename) root_tag['Data']['GameRules'][ 'commandBlockOutput'].value = 'false' root_tag.save(self.world.filename) else: print "Skipping save! (--write disabled)" result = True return result
def generate(self, cache_path, version): '''Generate a treasure hunt''' # the treasure hunt name is stored in dungeon_name and is built here # because we don't have a ruins[] section _thnames = (('{owners} lost booty', 10), ('{owners} treasure', 10), ('{owners} secret loot', 10), ('Lost treasure of {owner}', 10), ('Hidden gold of {owner}', 10), ('{owners} hidden gold', 10), ('The secret hoard of {owner}', 10), ('Buried treasure of {owner} the Pirate', 10), ('{owners} college fund', 1)) # Pick a starting size. self.xsize = 1 self.zsize = 1 self.steps = randint(cfg.min_steps, cfg.max_steps) self.min_distance = cfg.min_distance self.max_distance = cfg.max_distance located = False result = False # Find a landmark, if we can. # Manual landmark if cfg.offset is not '': print 'Treasure hunt step: {1}'.format(self.steps) self.position = str2Vec(cfg.offset) self.position.x = self.position.x & ~15 self.position.z = self.position.z & ~15 # XXX bury the chest below ground self.bury() print "Location set to: ", self.position # Search for a location. else: print "Searching for a suitable location..." located = self.findlocation() if (located is False): print 'Unable to place any more treasure hunts.' else: print 'Treasure hunt steps: {0}'.format(self.steps) print "Location: ", self.position # Generate! if (located is True): # We have a final size, so let's initialize some things. self.heightmap = numpy.zeros((self.room_size, self.room_size)) # Set the seed if requested. if (self.args.seed is not None): seed(self.args.seed) print 'Seed:', self.args.seed # Now we know the biome, we can setup a name generator self.namegen = namegenerator.namegenerator(None, theme='pirate') print 'Theme:', self.namegen.theme self.owner = self.namegen.genroyalname() print 'Owner:', self.owner print "Location: ", self.position print "Generating landmarks..." self.genlandmarks() # Name this place if self.owner.endswith("s"): owners = self.owner + "'" else: owners = self.owner + "'s" self.dinfo['dungeon_name'] = weighted_choice(_thnames) self.dungeon_name = self.dinfo['dungeon_name'].format( owner=self.owner, owners=owners) self.dinfo['full_name'] = self.dungeon_name print "Treasure hunt name:", self.dungeon_name self.renderlandmarks() self.placechests() if cfg.th_spawners is True: self.placespawners() self.processBiomes() # Signature self.setblock(Vec(0, 0, 0), materials.Chest, 0, hide=True) self.tile_ents[Vec(0, 0, 0)] = encodeTHuntInfo(self, version) # Add to the dungeon cache. key = '%s,%s' % ( self.position.x, self.position.z, ) # we need the info if making multiple hunts, to avoid # all previous landmarks #self.thunt_cache[key] = self.tile_ents[Vec(0, 0, 0)] self.thunt_cache[key] = True # copy results to the world self.applychanges() # Relight these chunks. if (self.args.write is True and self.args.skiprelight is False): # Super ugly, but does progress bars for lighting. for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) h = RelightHandler() logging.basicConfig(stream=h, level=logging.INFO) self.world.generateLights() h.done() logging.getLogger().level = logging.CRITICAL for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # Saving here allows us to pick up where we left off if we stop. if (self.args.write is True): print "Saving..." self.world.saveInPlace() saveTHuntCache(cache_path, self.thunt_cache) saveChunkCache(cache_path, self.chunk_cache) # make sure commandBlockOutput is false. root_tag = nbt.load(self.world.filename) root_tag['Data']['GameRules'][ 'commandBlockOutput'].value = 'false' root_tag.save(self.world.filename) else: print "Skipping save! (--write disabled)" result = True return result
def load_file(): global test_file test_file = nbt.load(buf=test_data)
def genWallMap(level, box, options): mapScale = options["Scale"] wallMapCentreX = options["x"] wallMapCentreZ = options["z"] gridAlign = options["Align with Grid"] renderMaps = options["Render Maps"] if dimNo != 0: dataFolder = level.parentWorld.worldFolder.getFolderPath("data") else: dataFolder = level.worldFolder.getFolderPath("data") if os.path.exists(os.path.join(dataFolder, "idcounts.dat")): idcountsTag = nbt.load(os.path.join(dataFolder, "idcounts.dat")) # Value of last existing map, new map should be map_(mapCount+1) mapCount = idcountsTag["map"].value else: mapCount = -1 if gridAlign: wallMapCentreX = int(round(wallMapCentreX/8.0))*8 wallMapCentreZ = int(round(wallMapCentreZ/8.0))*8 # if the box is not 1 thick if box.width != 1 and box.length != 1: raise Exception("The selection box needs to be 1 block thick") for chunk, slices, point in level.getChunkSlices(box): if chunk.Blocks[slices].any(): raise Exception("The selection box should be clear of blocks") # facing # 0 : south, +x map left to right # 1 : west, +z # 2 : north, -x # 3 : east, -z positive = 0 negative = 0 if box.width == 1: # wall map along y-z plane for chunk, slices, point in level.getChunkSlices(pymclevel.box.BoundingBox(box.origin + (1, 0, 0), box.size)): positive += chunk.Blocks[slices][chunk.Blocks[slices] != 0].size for chunk, slices, point in level.getChunkSlices(pymclevel.box.BoundingBox(box.origin + (-1, 0, 0), box.size)): negative += chunk.Blocks[slices][chunk.Blocks[slices] != 0].size if positive > negative: facing = 1 else: facing = 3 wallMapWidth = box.length else: # wall map along x-y plane for chunk, slices, point in level.getChunkSlices(pymclevel.box.BoundingBox(box.origin + (0, 0, 1), box.size)): positive += chunk.Blocks[slices][chunk.Blocks[slices] != 0].size for chunk, slices, point in level.getChunkSlices(pymclevel.box.BoundingBox(box.origin + (0, 0, -1), box.size)): negative += chunk.Blocks[slices][chunk.Blocks[slices] != 0].size if positive > negative: facing = 2 else: facing = 0 wallMapWidth = box.width wallMapHeight = box.height for chunk, slices, point in level.getChunkSlices(pymclevel.box.BoundingBox(box.origin + (1*[0, 1, 0, -1][facing], 0, 1*[-1, 0, 1, 0][facing], box.size))): if not chunk.Blocks[slices].all(): raise Exception("The selection box should be against a wall") def itemFramePosIter(box, facing): if facing == 0: return ((x, y, box.minz) for y in xrange(box.maxy-1, box.miny-1, -1) for x in xrange(box.minx, box.maxx)) elif facing == 1: return ((box.minx, y, z) for y in xrange(box.maxy-1, box.miny-1, -1) for z in xrange(box.minz, box.maxz)) elif facing == 2: return ((x, y, box.minz) for y in xrange(box.maxy-1, box.miny-1, -1) for x in xrange(box.maxx-1, box.minx-1, -1)) elif facing == 3: return ((box.minx, y, z) for y in xrange(box.maxy-1, box.miny-1, -1) for z in xrange(box.maxz-1, box.minz-1, -1)) def mapCentreIter(wallMapCentreX, wallMapCentreZ, wallMapWidth, wallMapHeight, mapScale, upDir): mapWidthInBlocks = 128 * 2**mapScale if upDir == 2: topLeftMapCentreX = wallMapCentreX - wallMapWidth*mapWidthInBlocks/2 + mapWidthInBlocks/2 topLeftMapCentreZ = wallMapCentreZ - wallMapHeight*mapWidthInBlocks/2 + mapWidthInBlocks/2 for h in xrange(wallMapHeight): for w in xrange(wallMapWidth): yield (topLeftMapCentreX + w * mapWidthInBlocks, topLeftMapCentreZ + h * mapWidthInBlocks) elif upDir == 3: topLeftMapCentreX = wallMapCentreX + wallMapHeight*mapWidthInBlocks/2 - mapWidthInBlocks/2 topLeftMapCentreZ = wallMapCentreZ - wallMapWidth*mapWidthInBlocks/2 + mapWidthInBlocks/2 for h in xrange(wallMapHeight): for w in xrange(wallMapWidth): yield (topLeftMapCentreX - h * mapWidthInBlocks, topLeftMapCentreZ + w * mapWidthInBlocks) elif upDir == 0: topLeftMapCentreX = wallMapCentreX + wallMapWidth*mapWidthInBlocks/2 - mapWidthInBlocks/2 topLeftMapCentreZ = wallMapCentreZ + wallMapHeight*mapWidthInBlocks/2 - mapWidthInBlocks/2 for h in xrange(wallMapHeight): for w in xrange(wallMapWidth): yield (topLeftMapCentreX - w * mapWidthInBlocks, topLeftMapCentreZ - h * mapWidthInBlocks) elif upDir == 1: topLeftMapCentreX = wallMapCentreX - wallMapHeight*mapWidthInBlocks/2 + mapWidthInBlocks/2 topLeftMapCentreZ = wallMapCentreZ + wallMapWidth*mapWidthInBlocks/2 - mapWidthInBlocks/2 for h in xrange(wallMapHeight): for w in xrange(wallMapWidth): yield (topLeftMapCentreX + h * mapWidthInBlocks, topLeftMapCentreZ - w * mapWidthInBlocks) upDir = {"North":2, "East":3, "South":0, "West":1}[options["Up is"]] itemRotation = [2, 1, 0, 3][upDir] progressBarMapCount = 0 numMaps = wallMapWidth * wallMapHeight numCols = numMaps * 128 for itemFramePos, mapCentre in itertools.izip(itemFramePosIter(box, facing), mapCentreIter(wallMapCentreX, wallMapCentreZ, wallMapWidth, wallMapHeight, mapScale, upDir)): mapCount += 1 mapTag = makeMapTag(*mapCentre, scale=mapScale) if renderMaps: for column in renderMap(level, mapTag): yield progressBarMapCount * 128 + column, numCols, "Map: "+str(progressBarMapCount)+"/"+str(numMaps) saveMapTag(level, mapTag, mapCount) mapItem = makeMapItemTag(mapCount) itemFrame = makeItemFrameEntity(*itemFramePos, facing=facing, itemtag=mapItem, itemRotation=itemRotation) level.addEntity(itemFrame) progressBarMapCount += 1 if mapCount >= 0: idcountsTag = TAG_Compound() idcountsTag["map"] = TAG_Short(mapCount) idcountsTag.save(os.path.join(dataFolder, "idcounts.dat"))
def buildItemTag(self,i): # If it's a binary NBT file, just load it if i.file != '': item_tag = nbt.load(i.file) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag # Otherwise, we will build the compound item_tag = nbt.TAG_Compound() # Standard stuff item_tag['id'] = nbt.TAG_String(i.id) item_tag['Damage'] = nbt.TAG_Short(i.damage) # Enchantments if len(i.enchantments) > 0: item_tag['tag'] = nbt.TAG_Compound() if (i.flag == 'ENCH_BOOK'): item_tag['tag']['StoredEnchantments'] = nbt.TAG_List() elist = item_tag['tag']['StoredEnchantments'] else: item_tag['tag']['ench'] = nbt.TAG_List() elist = item_tag['tag']['ench'] for e in i.enchantments: e_tag = nbt.TAG_Compound() e_tag['id'] = nbt.TAG_Short(e['id']) e_tag['lvl'] = nbt.TAG_Short(e['lvl']) elist.append(e_tag) # Custom Potion Effects if i.p_effect != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() # Is this a 'basic' potion i.e. no custom effects list if (i.p_effect.replace(',','').replace('-','').isdigit()): item_tag['tag']['CustomPotionEffects'] = nbt.TAG_List() elist = item_tag['tag']['CustomPotionEffects'] for e in i.p_effect.split(','): id, amp, dur = e.split('-') e_tag = nbt.TAG_Compound() e_tag['Id'] = nbt.TAG_Byte(id) e_tag['Amplifier'] = nbt.TAG_Byte(amp) e_tag['Duration'] = nbt.TAG_Int(dur) # Flags for hiding potion particles if i.flag == 'HIDE_PARTICLES' or i.flag == 'HIDE_ALL': e_tag['ShowParticles'] = nbt.TAG_Byte(0) elist.append(e_tag) # If we have a flagparam, use it for the potion's colour if i.flagparam != '': item_tag['tag']['CustomPotionColor'] = nbt.TAG_Int(i.flagparam) else: item_tag['tag']['Potion'] = nbt.TAG_String(i.p_effect) # For basic potions there is no need for a custom name i.customname = '' # Flag for hiding additional text if i.flag == 'HIDE_EFFECTS' or i.flag == 'HIDE_ALL': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['HideFlags'] = nbt.TAG_Int(63) # 63 = Hide everything # Naming if i.customname != '': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Name'] = nbt.TAG_String(i.customname) # Lore Text if i.lore != '' or i.flag == 'FORTUNE': try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() item_tag['tag']['display']['Lore'] = nbt.TAG_List() if i.flag == 'FORTUNE': item_tag['tag']['display'][ 'Name'] = nbt.TAG_String('Fortune Cookie') i.lore = self.loadrandfortune() loredata = textwrap.wrap(self.ConvertEscapeChars(i.lore), 30) for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(loretext)) else: loredata = i.lore.split(':') for loretext in loredata[:10]: item_tag['tag']['display']['Lore'].append( nbt.TAG_String(self.ConvertEscapeChars(loretext[:50]))) # Dyed if (i.flag == 'DYED'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() try: item_tag['tag']['display'] except: item_tag['tag']['display'] = nbt.TAG_Compound() if i.flagparam == '': item_tag['tag']['display']['color'] = nbt.TAG_Int( random.randint( 0, 16777215)) else: item_tag['tag']['display']['color'] = nbt.TAG_Int(i.flagparam) # special cases for written books and paintings elif (i.flag == 'WRITTEN'): item_tag = self.loadrandbooktext() elif (i.flag == 'PAINT'): item_tag = self.loadrandpainting() # Tags for this dungeon's flag elif (i.flag == 'DUNGEON_FLAG'): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['BlockEntityTag'] = nbt.TAG_Compound() item_tag['tag']['BlockEntityTag']['Base'] = nbt.TAG_Int(self.flag['Base']) item_tag['tag']['BlockEntityTag']['Patterns'] = nbt.TAG_List() for p in self.flag['Patterns']: q = nbt.TAG_Compound() q['Color'] = nbt.TAG_Int(p[0]) q['Pattern'] = nbt.TAG_String(p[1]) item_tag['tag']['BlockEntityTag']['Patterns'].append(q) elif (i.flag.startswith('ENTITYTAG:')): try: item_tag['tag'] except: item_tag['tag'] = nbt.TAG_Compound() item_tag['tag']['EntityTag'] = nbt.TAG_Compound() # ENTITYTAG: is ten characters, we want everything afterwards item_tag['tag']['EntityTag']['id'] = nbt.TAG_String(i.flag[10:]) # Set the slot and count if i.slot != None: item_tag['Slot'] = nbt.TAG_Byte(i.slot) item_tag['Count'] = nbt.TAG_Byte(i.count) return item_tag