Example #1
0
 def getTAGStructure(self):
     tag = nbt.TAG_Compound()
     tag["Name"] = nbt.TAG_String(self.name)
     tag["RenderType"] = nbt.TAG_String(self.renderType)
     tag["DisplayName"] = nbt.TAG_String(self.displayName)
     tag["CriteriaName"] = nbt.TAG_String(self.criteria)
     return tag
Example #2
0
  def __init__(self, cmd="", hover="", block="I", d="u", cond=False, redstone=False, time=0, first=False):
    name = "minecraft:" + self.nameMap[block]
    dv = self.dMap[d]
    if cond:
      dv += 8
    nbtData = nbt.TAG_Compound("", [])
    nbtData.add(nbt.TAG_Byte("auto", int(not redstone)))
    nbtData.add(nbt.TAG_String("Command", cmd))
    nbtData.add(nbt.TAG_String("CustomName", hover))
    nbtData.add(nbt.TAG_Byte("powered", int(block == "R" and not redstone)))
    if time == 0 and not first:
      nbtData.add(nbt.TAG_Int("Version", 8))
    else:
      nbtData.add(nbt.TAG_Int("Version", 9))
      nbtData.add(nbt.TAG_Byte("ExecuteOnFirstTick", int(first)))
      nbtData.add(nbt.TAG_Int("TickDelay", time))

    nbtData.add(nbt.TAG_Byte("conditionMet", 0))
    nbtData.add(nbt.TAG_String("id", "CommandBlock"))
    nbtData.add(nbt.TAG_Byte("isMovable", 1))
    nbtData.add(nbt.TAG_Int("LPCommandMode", 0)) # Not sure what these LPModes do. This works.
    nbtData.add(nbt.TAG_Byte("LPConditionalMode", 0))
    nbtData.add(nbt.TAG_Byte("LPRedstoneMode", 0))
    nbtData.add(nbt.TAG_Long("LastExecution", 0))
    nbtData.add(nbt.TAG_String("LastOutput", ""))
    nbtData.add(nbt.TAG_List("LastOutputParams", []))
    nbtData.add(nbt.TAG_Int("SuccessCount", 0))
    nbtData.add(nbt.TAG_Byte("TrackOutput", 1))
    super().__init__(name, dv, nbtData)
Example #3
0
    def Create(cls, tileEntityID, pos=(0, 0, 0), **kw):
        tileEntityTag = nbt.TAG_Compound()
        # Refresh the MCEDIT_DEFS and MCEDIT_IDS objects
        from pymclevel import MCEDIT_DEFS, MCEDIT_IDS
        _id = MCEDIT_DEFS.get(tileEntityID, tileEntityID)
        tileEntityTag["id"] = nbt.TAG_String(_id)
        base = cls.baseStructures.get(tileEntityID, None)
        if base:
            for (name, tag) in base:
                tileEntityTag[name] = tag()
                if tileEntityID == "Control":
                    if name == "CustomName":
                        tileEntityTag[name] = nbt.TAG_String("@")
                    elif name == "SuccessCount":
                        tileEntityTag[name] = nbt.TAG_Int(0)
                elif tileEntityID == "MobSpawner":
                    entity = kw.get("entity")
                    if name == "EntityId":
                        tileEntityTag[name] = nbt.TAG_String(MCEDIT_DEFS.get("Pig", "Pig"))
                    if name == "SpawnData":
                        spawn_id = nbt.TAG_String(MCEDIT_DEFS.get("Pig", "Pig"), "id")
                        tileEntityTag["SpawnData"] = tag()
                        if entity:
                            for k, v in entity.iteritems():
                                tileEntityTag["SpawnData"][k] = deepcopy(v)
                        else:
                            tileEntityTag["SpawnData"].add(spawn_id)

        cls.setpos(tileEntityTag, pos)
        return tileEntityTag
Example #4
0
 def toNBT(self):
     root = nbt.TAG_Compound()
     root['Name'] = nbt.TAG_String('{}:{}'.format(self._resource_location,
                                                  self._basename))
     if self._properties:
         props = nbt.TAG_Compound()
         for (key, value) in self._properties.iteritems():
             props[key] = nbt.TAG_String(value)
         root['Properties'] = props
     return root
Example #5
0
    def Create(cls, tileEntityID, pos=(0, 0, 0), **kw):
        tileEntityTag = nbt.TAG_Compound()
        tileEntityTag["id"] = nbt.TAG_String(tileEntityID)
        base = cls.baseStructures.get(tileEntityID, None)
        if base:
            for (name, tag) in base:
                tileEntityTag[name] = tag()
                if name == "CustomName" and tileEntityID == "Control":
                    tileEntityTag[name] = nbt.TAG_String("@")

        cls.setpos(tileEntityTag, pos)
        return tileEntityTag
Example #6
0
    def saveToFile(self, filename):
        schematicDat = nbt.TAG_Compound()
        schematicDat.name = "Mega Schematic"

        schematicDat["Width"] = nbt.TAG_Int(self.size[0])
        schematicDat["Height"] = nbt.TAG_Int(self.size[1])
        schematicDat["Length"] = nbt.TAG_Int(self.size[2])
        schematicDat["Materials"] = nbt.TAG_String(self.materials.name)

        schematicDat.save(self.worldFolder.getFilePath("schematic.dat"))

        basedir = self.worldFolder.filename
        assert os.path.isdir(basedir)

        with closing(
                zipfile.ZipFile(filename,
                                "w",
                                zipfile.ZIP_STORED,
                                allowZip64=True)) as z:
            for root, dirs, files in os.walk(basedir):
                # NOTE: ignore empty directories
                for fn in files:
                    absfn = os.path.join(root, fn)
                    shutil.move(absfn,
                                absfn.replace("##MCEDIT.TEMP##" + os.sep, ""))
                    absfn = absfn.replace("##MCEDIT.TEMP##" + os.sep, "")
                    zfn = absfn[len(basedir) +
                                len(os.sep):]  # XXX: relative path
                    z.write(absfn, zfn)
def createschematic():
    a = (128 * 129 * (maxup + abs(maxdown) + 1))
    schematic = nbt.NBTFile()
    schematic["Height"] = nbt.TAG_Short(value=(abs(maxdown) + maxup + 1))
    schematic["Length"] = nbt.TAG_Short(value=129)
    schematic["Width"] = nbt.TAG_Short(value=128)
    tempblocks = array.array('B', [0] * a)
    tempdata = array.array('B', [0] * a)
    for x in xrange(128):
        for y in xrange(128):
            tempblocks[s(x, y)] = blockid[tempcolors[m(x, y)]]
            tempdata[s(x, y)] = blockdata[tempcolors[m(x, y)]]
        tempblocks[s(x, 128)] = 3
        tempdata[s(x, 128)] = 0
    schematic["Blocks"] = nbt.TAG_Byte_Array()
    schematic["Data"] = nbt.TAG_Byte_Array()
    schematic["Blocks"].value = bytearray(tempblocks)
    schematic["Data"].value = bytearray(tempdata)
    schematic["Materials"] = nbt.TAG_String(value="Alpha")
    print "Writing file..."
    schematic.write_file(schematicpath)
    print "Schematic successfully created!"
    print "max height up: " + repr(maxup)
    print "max height down: " + repr(abs(maxdown))
    print "Minimum height you should build at: " + repr(maxup + 64)
Example #8
0
    def __init__(self,
                 filename=None,
                 root_tag=None,
                 size=None,
                 mats=alphaMaterials):
        if not 'blockstateToID' in globals().keys():
            from materials import blockstateToID
        self._author = None
        self._blocks = None
        self._palette = None
        self._entities = []
        self._tile_entities = None
        self._size = None
        self._version = None
        self._mat = mats

        if filename:
            root_tag = nbt.load(filename)

        if root_tag:
            self._root_tag = root_tag
            self._size = (self._root_tag["size"][0].value,
                          self._root_tag["size"][1].value,
                          self._root_tag["size"][2].value)

            self._author = self._root_tag.get("author", nbt.TAG_String()).value
            self._version = self._root_tag.get("version", nbt.TAG_Int(1)).value
            self._version = self._root_tag.get("DataVersion",
                                               nbt.TAG_Int(1)).value

            self._palette = self.__toPythonPrimitive(self._root_tag["palette"])

            self._blocks = zeros(self.Size, dtype=tuple)
            self._blocks.fill((0, 0))
            self._entities = []
            self._tile_entities = zeros(self.Size, dtype=nbt.TAG_Compound)
            self._tile_entities.fill({})

            for block in self._root_tag["blocks"]:
                x, y, z = [p.value for p in block["pos"].value]
                self._blocks[x, y, z] = blockstateToID(
                    *self.get_state(block["state"].value))
                if "nbt" in block:
                    compound = nbt.TAG_Compound()
                    compound.update(block["nbt"])
                    self._tile_entities[x, y, z] = compound

            for e in self._root_tag["entities"]:
                entity = e["nbt"]
                entity["Pos"] = e["pos"]
                self._entities.append(entity)
        elif size:
            self._root_tag = nbt.TAG_Compound()
            self._size = size

            self._blocks = zeros(self.Size, dtype=tuple)
            self._blocks.fill((0, 0))
            self._entities = []
            self._tile_entities = zeros(self.Size, dtype=nbt.TAG_Compound)
            self._tile_entities.fill({})
Example #9
0
    def __init__(self, cx, cz, world, data=None, create=False):
        """
        :param cx, cz int, int Coordinates of the chunk
        :param data List of 3 strings. (83200 bytes of terrain data, tile-entity data, entity data)
        :param world PocketLeveldbWorld, instance of the world the chunk belongs too
        """
        self.chunkPosition = (cx, cz)
        self.world = world

        if create:
            self.Blocks = numpy.zeros(32768, 'uint16')
            self.Data = numpy.zeros(16384, 'uint8')
            self.SkyLight = numpy.zeros(16384, 'uint8')
            self.BlockLight = numpy.zeros(16384, 'uint8')
            self.DirtyColumns = numpy.zeros(256, 'uint8')
            self.GrassColors = numpy.zeros(1024, 'uint8')

            self.TileEntities = nbt.TAG_List()
            self.Entities = nbt.TAG_List()

        else:
            terrain = numpy.fromstring(data[0], dtype='uint8')
            if data[1] is not None:
                TileEntities = loadNBTCompoundList(data[1])
                self.TileEntities = nbt.TAG_List(TileEntities,
                                                 list_type=nbt.TAG_COMPOUND)

            if data[2] is not None:
                Entities = loadNBTCompoundList(data[2])
                # PE saves entities with their int ID instead of string name. We swap them to make it work in mcedit.
                # Whenever we save an entity, we need to make sure to swap back.
                invertEntities = {
                    v: k
                    for k, v in entity.PocketEntity.entityList.items()
                }
                for ent in Entities:
                    # Get the string id, or a build one
                    v = ent["id"].value
                    id = invertEntities.get(v, "Entity %s" % v)
                    # Add the built one to the entities
                    if id not in entity.PocketEntity.entityList.keys():
                        logger.warning("Found unknown entity '%s'" % v)
                        entity.PocketEntity.entityList[id] = v
                    ent["id"] = nbt.TAG_String(id)
                self.Entities = nbt.TAG_List(Entities,
                                             list_type=nbt.TAG_COMPOUND)

            self.Blocks, terrain = terrain[:32768], terrain[32768:]
            self.Data, terrain = terrain[:16384], terrain[16384:]
            self.SkyLight, terrain = terrain[:16384], terrain[16384:]
            self.BlockLight, terrain = terrain[:16384], terrain[16384:]
            self.DirtyColumns, terrain = terrain[:256], terrain[256:]

            # Unused at the moment. Might need a special editor? Maybe hooked up to biomes?
            self.GrassColors = terrain[:1024]

        self._unpackChunkData()
        self.shapeChunkData()
Example #10
0
    def TileEntities(self):
        chestTag = nbt.TAG_Compound()
        chestTag["id"] = nbt.TAG_String("Chest")
        chestTag["Items"] = nbt.TAG_List(self.root_tag["Inventory"])
        chestTag["x"] = nbt.TAG_Int(0)
        chestTag["y"] = nbt.TAG_Int(0)
        chestTag["z"] = nbt.TAG_Int(0)

        return nbt.TAG_List([chestTag], name="TileEntities")
Example #11
0
    def Create(cls, tileEntityID, pos=(0, 0, 0), **kw):
        tileEntityTag = nbt.TAG_Compound()
        tileEntityTag["id"] = nbt.TAG_String(tileEntityID)
        base = cls.baseStructures.get(tileEntityID, None)
        if base:
            for (name, tag) in base:
                tileEntityTag[name] = tag()
                if tileEntityID == "Control":
                    if name == "CustomName":
                        tileEntityTag[name] = nbt.TAG_String("@")
                    elif name == "SuccessCount":
                        tileEntityTag[name] = nbt.TAG_Int(0)
                elif tileEntityID == "MobSpawner":
                    if name == "EntityId":
                        tileEntityTag[name] = nbt.TAG_String("Pig")

        cls.setpos(tileEntityTag, pos)
        return tileEntityTag
Example #12
0
    def Create(cls, tileEntityID, **kw):
        tileEntityTag = nbt.TAG_Compound()
        tileEntityTag["id"] = nbt.TAG_String(tileEntityID)
        base = cls.baseStructures.get(tileEntityID, None)
        if base:
            for (name, tag) in base:
                tileEntityTag[name] = tag()

        cls.setpos(tileEntityTag, (0, 0, 0))
        return tileEntityTag
Example #13
0
 def _savePalette(self, layer):
   blocks = self.blocks[layer].swapaxes(1, 2).reshape(4096) # Y and Z saved in a inverted order
   blockIDs = np.empty(4096, dtype=np.uint32)
   palette = []
   mapping = {}
   for i, block in enumerate(blocks):
     # Generate the palette nbt for the given block
     short = (block.name, str(block.properties))
     if short not in mapping:
       if isinstance(block.properties, int): # 1.12
         palette.append(nbt.TAG_Compound("", [nbt.TAG_String("name", block.name), nbt.TAG_Short("val", block.properties)]))
       else: # 1.13
         palette.append(nbt.TAG_Compound("", [
           nbt.TAG_String("name", block.name),
           nbt.TAG_Compound("states", block.properties),
           nbt.TAG_Int("version", 17629200)
         ]))
       mapping[short] = len(palette) - 1
     blockIDs[i] = mapping[short]
   return palette, blockIDs
Example #14
0
    def savedData(self):
        """
        Returns the data of the chunk to save to the database.
        :return: str of 83200 bytes of chunk data.
        """
        def packData(dataArray):
            """
            Repacks the terrain data to Mojang's leveldb library's format.
            """
            assert dataArray.shape[2] == self.world.Height

            data = numpy.array(dataArray).reshape(16, 16,
                                                  self.world.Height / 2, 2)
            data[..., 1] <<= 4
            data[..., 1] |= data[..., 0]
            return numpy.array(data[:, :, :, 1])

        if self.dirty:
            # elements of DirtyColumns are bitfields. Each bit corresponds to a
            # 16-block segment of the column. We set all of the bits because
            # we only track modifications at the chunk level.
            self.DirtyColumns[:] = 255

        with nbt.littleEndianNBT():
            entityData = ""
            tileEntityData = ""

            for ent in self.TileEntities:
                tileEntityData += ent.save(compressed=False)

            for ent in self.Entities:
                v = ent["id"].value
                #                 ent["id"] = nbt.TAG_Int(entity.PocketEntity.entityList[v])
                id = entity.PocketEntity.getNumId(v)
                #                 print id
                if id >= 1000:
                    print id
                    print type(ent)
                    print ent
                ent['id'] = nbt.TAG_Int(id)
                entityData += ent.save(compressed=False)
                # We have to re-invert after saving otherwise the next save will fail.
                ent["id"] = nbt.TAG_String(v)

        terrain = ''.join([
            self.Blocks.tostring(),
            packData(self.Data).tostring(),
            packData(self.SkyLight).tostring(),
            packData(self.BlockLight).tostring(),
            self.DirtyColumns.tostring(),
            self.GrassColors.tostring(),
        ])

        return terrain, tileEntityData, entityData
Example #15
0
    def testModify(self):
        level = self.testCreate()

        # Most of the value types work as expected. Here, we replace the entire tag with a TAG_String
        level["About"]["Author"] = nbt.TAG_String("YARRR~!")

        # Because the tag type usually doesn't change,
        # we can replace the string tag's value instead of replacing the entire tag.
        level["About"]["Author"].value = "Stew Pickles"

        # Remove members of a TAG_Compound using del, similar to a python dict.
        del (level["About"])

        # Replace all of the wood blocks with gold using a boolean index array
        blocks = level["Map"]["Blocks"].value
        blocks[blocks == 5] = 41

        level["Entities"][0] = nbt.TAG_Compound([
            nbt.TAG_String("Creeper", "id"),
            nbt.TAG_List([nbt.TAG_Double(d) for d in (1, 1, 1)], "Pos")
        ])
Example #16
0
    def TileEntities(self):
        chestTag = nbt.TAG_Compound()
        chest_id = "Chest"
        split_ver = self.gameVersion.split('.')
        if int(split_ver[0]) >= 1 and int(split[1]) >= 11:
            chest_id = "minecraft:chest"
        chestTag["id"] = nbt.TAG_String(chest_id)
        chestTag["Items"] = nbt.TAG_List(self.root_tag["Inventory"])
        chestTag["x"] = nbt.TAG_Int(0)
        chestTag["y"] = nbt.TAG_Int(0)
        chestTag["z"] = nbt.TAG_Int(0)

        return nbt.TAG_List([chestTag], name="TileEntities")
Example #17
0
def extractZipSchematicFromIter(sourceLevel,
                                box,
                                zipfilename=None,
                                entities=True):
    # converts classic blocks to alpha
    # probably should only apply to alpha levels

    if zipfilename is None:
        zipfilename = tempfile.mktemp("zipschematic")

    p = sourceLevel.adjustExtractionParameters(box)
    if p is None:
        return
    sourceBox, destPoint = p

    destPoint = (0, 0, 0)

    tempfolder = tempfile.mktemp("schematic")
    try:
        tempSchematic = MCInfdevOldLevel(tempfolder, create=True)
        tempSchematic.materials = sourceLevel.materials

        for i in tempSchematic.copyBlocksFromIter(sourceLevel,
                                                  sourceBox,
                                                  destPoint,
                                                  entities=entities,
                                                  create=True):
            yield i
        tempSchematic.saveInPlace(
        )  # lights not needed for this format - crashes minecraft though

        schematicDat = nbt.TAG_Compound()
        schematicDat.name = "Mega Schematic"

        schematicDat["Width"] = nbt.TAG_Int(sourceBox.size[0])
        schematicDat["Height"] = nbt.TAG_Int(sourceBox.size[1])
        schematicDat["Length"] = nbt.TAG_Int(sourceBox.size[2])
        schematicDat["Materials"] = nbt.TAG_String(
            tempSchematic.materials.name)
        schematicDat.save(os.path.join(tempfolder, "schematic.dat"))

        zipdir(tempfolder, zipfilename)

        import mclevel
        yield mclevel.fromFile(zipfilename)
    finally:
        # We get here if the generator is GCed also
        if os.path.exists(tempfolder):
            shutil.rmtree(tempfolder, False)
Example #18
0
    def testCreate(self):
        "Create an indev level."

        "The root of an NBT file is always a TAG_Compound."
        level = nbt.TAG_Compound(name="MinecraftLevel")

        "Subtags of a TAG_Compound are automatically named when you use the [] operator."
        level["About"] = nbt.TAG_Compound()
        level["About"]["Author"] = nbt.TAG_String("codewarrior")

        level["Environment"] = nbt.TAG_Compound()
        level["Environment"]["SkyBrightness"] = nbt.TAG_Byte(16)
        level["Environment"]["SurroundingWaterHeight"] = nbt.TAG_Short(32)

        "You can also create and name a tag before adding it to the compound."
        spawn = nbt.TAG_List(
            (nbt.TAG_Short(100), nbt.TAG_Short(45), nbt.TAG_Short(55)))
        spawn.name = "Spawn"

        mapTag = nbt.TAG_Compound()
        mapTag.add(spawn)
        mapTag.name = "Map"
        level.add(mapTag)

        "I think it looks more familiar with [] syntax."

        l, w, h = 128, 128, 128
        mapTag["Height"] = nbt.TAG_Short(h)  # y dimension
        mapTag["Length"] = nbt.TAG_Short(l)  # z dimension
        mapTag["Width"] = nbt.TAG_Short(w)  # x dimension

        "Byte arrays are stored as numpy.uint8 arrays. "

        mapTag["Blocks"] = nbt.TAG_Byte_Array()
        mapTag["Blocks"].value = numpy.zeros(
            l * w * h, dtype=numpy.uint8)  # create lots of air!

        "The blocks array is indexed (y,z,x) for indev levels, so reshape the blocks"
        mapTag["Blocks"].value.shape = (h, l, w)

        "Replace the bottom layer of the indev level with wood"
        mapTag["Blocks"].value[0, :, :] = 5

        "This is a great way to learn the power of numpy array slicing and indexing."

        mapTag["Data"] = nbt.TAG_Byte_Array()
        mapTag["Data"].value = numpy.zeros(l * w * h, dtype=numpy.uint8)

        return level
Example #19
0
 def getTAGStructure(self):
     tag = nbt.TAG_Compound()
     tag["Name"] = nbt.TAG_String(self.name)
     tag["DisplayName"] = nbt.TAG_String(self.displayName)
     tag["Prefix"] = nbt.TAG_String(self.prefix)
     tag["Suffix"] = nbt.TAG_String(self.suffix)
     if self.color != None:
         tag["TeamColor"] = nbt.TAG_String(self.color)
     tag["NameTagVisibility"] = nbt.TAG_String(self.nametags)
     tag["DeathMessageVisibility"] = nbt.TAG_String(self.deathMessage)
     tag["AllowFriendlyFire"] = nbt.TAG_Byte(self.friendlyFire)
     tag["SeeFriendlyInvisibles"] = nbt.TAG_Byte(self.friendlyInvisibles)
     players = nbt.TAG_List()
     for member in self.teamMembers:
         players.append(nbt.TAG_String(member))
     tag["Players"] = players
     return tag
Example #20
0
    def testModify(self):
        level = self.testCreate()

        "Most of the value types work as expected. Here, we replace the entire tag with a TAG_String"
        level["About"]["Author"] = nbt.TAG_String("YARRR~!")

        "Because the tag type usually doesn't change, "
        "we can replace the string tag's value instead of replacing the entire tag."
        level["About"]["Author"].value = "Stew Pickles"

        "Remove members of a TAG_Compound using del, similar to a python dict."
        del (level["About"])

        "Replace all of the wood blocks with gold using a boolean index array"
        blocks = level["Map"]["Blocks"].value
        blocks[blocks == 5] = 41
Example #21
0
 def Create(cls, entityID, **kw):
     entityTag = nbt.TAG_Compound()
     entityTag["id"] = nbt.TAG_String(entityID)
     Entity.setpos(entityTag, (0, 0, 0))
     return entityTag
Example #22
0
    def copyWithOffset(cls, tileEntity, copyOffset, staticCommands, moveSpawnerPos, first, cancelCommandBlockOffset=False):
        # You'll need to use this function twice
        # The first time with first equals to True
        # The second time with first equals to False
        eTag = deepcopy(tileEntity)
        eTag['x'] = nbt.TAG_Int(tileEntity['x'].value + copyOffset[0])
        eTag['y'] = nbt.TAG_Int(tileEntity['y'].value + copyOffset[1])
        eTag['z'] = nbt.TAG_Int(tileEntity['z'].value + copyOffset[2])

        def num(x):
            try:
                return int(x)
            except ValueError:
                return float(x)

        def coordX(x, argument):
            if first:
                x = str(num(x)) + '!' + str(num(x) + copyOffset[0])
            elif argument and x.find("!") >= 0:
                x = x[x.index("!") + 1:]
                x = str(num(x) + copyOffset[0])
            elif not argument and x.find("!") >= 0:
                x = x[:x.index("!")]
            return x

        def coordY(y, argument):
            if first:
                y = str(num(y)) + '!' + str(num(y) + copyOffset[1])
            elif argument and y.find("!") >= 0:
                y = y[y.index("!") + 1:]
                y = str(num(y) + copyOffset[1])
            elif not argument and y.find("!") >= 0:
                y = y[:y.index("!")]
            return y

        def coordZ(z, argument):
            if first:
                z = str(num(z)) + '!' + str(num(z) + copyOffset[2])
            elif argument and z.find("!") >= 0:
                z = z[z.index("!") + 1:]
                z = str(num(z) + copyOffset[2])
            elif not argument and z.find("!") >= 0:
                z = z[:z.index("!")]
            return z

        def coords(x, y, z, argument):
            if x[0] != "~":
                x = coordX(x, argument)
            if y[0] != "~":
                y = coordY(y, argument)
            if z[0] != "~":
                z = coordZ(z, argument)
            return x, y, z

        if eTag['id'].value == 'MobSpawner' or MCEDIT_IDS.get(eTag['id'].value) == 'DEF_BLOCKS_MOB_SPAWNER':
            mobs = []
            if 'SpawnData' in eTag:
                mob = eTag['SpawnData']
                if mob:
                    mobs.append(mob)
            if 'SpawnPotentials' in eTag:
                potentials = eTag['SpawnPotentials']
                for p in potentials:
                    if 'properties' in p:
                        mobs.extend(p["Properties"])
                    elif 'Entity' in p:
                        mobs.extend(p["Entity"])

            for mob in mobs:
                # Why do we get a unicode object as tag 'mob'?
                if "Pos" in mob and mob != "Pos":
                    if first:
                        pos = Entity.pos(mob)
                        x, y, z = [str(part) for part in pos]
                        x, y, z = coords(x, y, z, moveSpawnerPos)
                        mob['Temp1'] = nbt.TAG_String(x)
                        mob['Temp2'] = nbt.TAG_String(y)
                        mob['Temp3'] = nbt.TAG_String(z)
                    elif 'Temp1' in mob and 'Temp2' in mob and 'Temp3' in mob:
                        x = mob['Temp1']
                        y = mob['Temp2']
                        z = mob['Temp3']
                        del mob['Temp1']
                        del mob['Temp2']
                        del mob['Temp3']
                        parts = []
                        for part in (x, y, z):
                            part = str(part)
                            part = part[13:len(part) - 2]
                            parts.append(part)
                        x, y, z = parts
                        pos = [float(p) for p in coords(x, y, z, moveSpawnerPos)]
                        Entity.setpos(mob, pos)

        if (eTag['id'].value == "Control" or MCEDIT_IDS.get(eTag['id'].value) == 'DEF_BLOCKS_COMMAND_BLOCK') and not cancelCommandBlockOffset:
            command = eTag['Command'].value
            oldCommand = command

            def selectorCoords(selector):
                old_selector = selector
                try:
                    char_num = 0
                    new_selector = ""
                    dont_copy = 0
                    if len(selector) > 4:
                        if '0' <= selector[3] <= '9':
                            new_selector = selector[:3]
                            end_char_x = selector.find(',', 4, len(selector) - 1)
                            if end_char_x == -1:
                                end_char_x = len(selector) - 1
                            x = selector[3:end_char_x]
                            x = coordX(x, staticCommands)
                            new_selector += x + ','

                            end_char_y = selector.find(',', end_char_x + 1, len(selector) - 1)
                            if end_char_y == -1:
                                end_char_y = len(selector) - 1
                            y = selector[end_char_x + 1:end_char_y]
                            y = coordY(y, staticCommands)
                            new_selector += y + ','

                            end_char_z = selector.find(',', end_char_y + 1, len(selector) - 1)
                            if end_char_z == -1:
                                end_char_z = len(selector) - 1
                            z = selector[end_char_y + 1:end_char_z]
                            z = coordZ(z, staticCommands)
                            new_selector += z + ',' + selector[end_char_z + 1:]

                        else:
                            for char in selector:
                                if dont_copy != 0:
                                    dont_copy -= 1
                                else:
                                    if (char != 'x' and char != 'y' and char != 'z') or letter:
                                        new_selector += char
                                        if char == '[' or char == ',':
                                            letter = False
                                        else:
                                            letter = True

                                    elif char == 'x' and not letter:
                                        new_selector += selector[char_num:char_num + 2]
                                        char_x = char_num + 2
                                        end_char_x = selector.find(',', char_num + 3, len(selector) - 1)
                                        if end_char_x == -1:
                                            end_char_x = len(selector) - 1
                                        x = selector[char_x:end_char_x]
                                        dont_copy = len(x) + 1
                                        x = coordX(x, staticCommands)
                                        new_selector += x

                                    elif char == 'y' and not letter:
                                        new_selector += selector[char_num:char_num + 2]
                                        char_y = char_num + 2
                                        end_char_y = selector.find(',', char_num + 3, len(selector) - 1)
                                        if end_char_y == -1:
                                            end_char_y = len(selector) - 1
                                        y = selector[char_y:end_char_y]
                                        dont_copy = len(y) + 1
                                        y = coordY(y, staticCommands)
                                        new_selector += y

                                    elif char == 'z' and not letter:
                                        new_selector += selector[char_num:char_num + 2]
                                        char_z = char_num + 2
                                        end_char_z = selector.find(',', char_num + 3, len(selector) - 1)
                                        if end_char_z == -1:
                                            end_char_z = len(selector) - 1
                                        z = selector[char_z:end_char_z]
                                        dont_copy = len(z) + 1
                                        z = coordZ(z, staticCommands)
                                        new_selector += z
                                char_num += 1
                    else:
                        new_selector = old_selector

                except:
                    new_selector = old_selector
                finally:
                    return new_selector

            try:
                execute = False
                Slash = False
                if command[0] == "/":
                    command = command[1:]
                    Slash = True

                # Adjust command coordinates.
                words = command.split(' ')

                i = 0
                for word in words:
                    if word[0] == '@':
                        words[i] = selectorCoords(word)
                    i += 1

                if command.startswith('execute'):
                    stillExecuting = True
                    execute = True
                    saving_command = ""
                    while stillExecuting:
                        if Slash:
                            saving_command += '/'
                        x, y, z = words[2:5]
                        words[2:5] = coords(x, y, z, staticCommands)
                        if words[5] == 'detect':
                            x, y, z = words[6:9]
                            words[6:9] = coords(x, y, z, staticCommands)
                            saving_command += ' '.join(words[:9])
                            words = words[9:]
                        else:
                            saving_command += ' '.join(words[:5])
                            words = words[5:]
                        command = ' '.join(words)
                        saving_command += ' '
                        Slash = False
                        if command[0] == "/":
                            command = command[1:]
                            Slash = True
                        words = command.split(' ')
                        if not command.startswith('execute'):
                            stillExecuting = False

                if (command.startswith('tp') and len(words) == 5) or command.startswith(
                        'particle') or command.startswith('replaceitem block') or (
                            command.startswith('spawnpoint') and len(words) == 5) or command.startswith('stats block') or (
                            command.startswith('summon') and len(words) >= 5):
                    x, y, z = words[2:5]
                    words[2:5] = coords(x, y, z, staticCommands)
                elif command.startswith('blockdata') or command.startswith('setblock') or (
                            command.startswith('setworldspawn') and len(words) == 4):
                    x, y, z = words[1:4]
                    words[1:4] = coords(x, y, z, staticCommands)
                elif command.startswith('playsound') and len(words) >= 6:
                    x, y, z = words[3:6]
                    words[3:6] = coords(x, y, z, staticCommands)
                elif command.startswith('clone'):
                    x1, y1, z1, x2, y2, z2, x, y, z = words[1:10]
                    x1, y1, z1 = coords(x1, y1, z1, staticCommands)
                    x2, y2, z2 = coords(x2, y2, z2, staticCommands)
                    x, y, z = coords(x, y, z, staticCommands)

                    words[1:10] = x1, y1, z1, x2, y2, z2, x, y, z
                elif command.startswith('fill'):
                    x1, y1, z1, x2, y2, z2 = words[1:7]
                    x1, y1, z1 = coords(x1, y1, z1, staticCommands)
                    x2, y2, z2 = coords(x2, y2, z2, staticCommands)

                    words[1:7] = x1, y1, z1, x2, y2, z2
                elif command.startswith('spreadplayers'):
                    x, z = words[1:3]
                    if x[0] != "~":
                        x = coordX(x, staticCommands)
                    if z[0] != "~":
                        z = coordZ(z, staticCommands)

                    words[1:3] = x, z
                elif command.startswith('worldborder center') and len(words) == 4:
                    x, z = words[2:4]
                    if x[0] != "~":
                        x = coordX(x, staticCommands)
                    if z[0] != "~":
                        z = coordZ(z, staticCommands)

                    words[2:4] = x, z
                if Slash:
                    command = '/'
                else:
                    command = ""
                command += ' '.join(words)

                if execute:
                    command = saving_command + command
                eTag['Command'].value = command
            except:
                eTag['Command'].value = oldCommand

        return eTag
Example #23
0
 def loadLevelDat(self):
     self.root_tag = nbt.load(os.path.join(self.path, 'level.dat'))
     self.gameVersion = self.root_tag['Data']['Version'].get(
         'Name', nbt.TAG_String('Unknown')).value
Example #24
0
    def __init__(self, shape=None, root_tag=None, filename=None, mats='Alpha'):
        """ shape is (x,y,z) for a new level's shape.  if none, takes
        root_tag as a TAG_Compound for an existing schematic file.  if
        none, tries to read the tag from filename.  if none, results
        are undefined. materials can be a MCMaterials instance, or one of
        "Classic", "Alpha", "Pocket" to indicate allowable blocks. The default
        is Alpha.

        block coordinate order in the file is y,z,x to use the same code as classic/indev levels.
        in hindsight, this was a completely arbitrary decision.

        the Entities and TileEntities are nbt.TAG_List objects containing TAG_Compounds.
        this makes it easy to copy entities without knowing about their insides.

        rotateLeft swaps the axes of the different arrays.  because of this, the Width, Height, and Length
        reflect the current dimensions of the schematic rather than the ones specified in the NBT structure.
        I'm not sure what happens when I try to re-save a rotated schematic.
        """

        if filename:
            self.filename = filename
            if None is root_tag and os.path.exists(filename):
                root_tag = nbt.load(filename)
        else:
            self.filename = None

        if mats in namedMaterials:
            self.materials = namedMaterials[mats]
        else:
            assert (isinstance(mats, MCMaterials))
            self.materials = mats

        if root_tag:
            self.root_tag = root_tag
            if "Materials" in root_tag:
                self.materials = namedMaterials[self.Materials]
            else:
                root_tag["Materials"] = nbt.TAG_String(self.materials.name)

            w = self.root_tag["Width"].value
            l = self.root_tag["Length"].value
            h = self.root_tag["Height"].value

            self._Blocks = self.root_tag["Blocks"].value.astype('uint16').reshape(h, l, w)  # _Blocks is y, z, x
            del self.root_tag["Blocks"]
            if "AddBlocks" in self.root_tag:
                # Use WorldEdit's "AddBlocks" array to load and store the 4 high bits of a block ID.
                # Unlike Minecraft's NibbleArrays, this array stores the first block's bits in the
                # 4 high bits of the first byte.

                size = (h * l * w)

                # If odd, add one to the size to make sure the adjacent slices line up.
                add = zeros(size + (size & 1), 'uint16')

                # Fill the even bytes with data
                add[::2] = self.root_tag["AddBlocks"].value

                # Copy the low 4 bits to the odd bytes
                add[1::2] = add[::2] & 0xf

                # Shift the even bytes down
                add[::2] >>= 4

                # Shift every byte up before merging it with Blocks
                add <<= 8
                self._Blocks |= add[:size].reshape(h, l, w)
                del self.root_tag["AddBlocks"]

            self.root_tag["Data"].value = self.root_tag["Data"].value.reshape(h, l, w)

            if "Biomes" in self.root_tag:
                self.root_tag["Biomes"].value.shape = (l, w)

        else:
            assert shape is not None
            root_tag = nbt.TAG_Compound(name="Schematic")
            root_tag["Height"] = nbt.TAG_Short(shape[1])
            root_tag["Length"] = nbt.TAG_Short(shape[2])
            root_tag["Width"] = nbt.TAG_Short(shape[0])

            root_tag["Entities"] = nbt.TAG_List()
            root_tag["TileEntities"] = nbt.TAG_List()
            root_tag["Materials"] = nbt.TAG_String(self.materials.name)

            self._Blocks = zeros((shape[1], shape[2], shape[0]), 'uint16')
            root_tag["Data"] = nbt.TAG_Byte_Array(zeros((shape[1], shape[2], shape[0]), uint8))

            root_tag["Biomes"] = nbt.TAG_Byte_Array(zeros((shape[2], shape[0]), uint8))

            self.root_tag = root_tag

        self.root_tag["Data"].value &= 0xF  # discard high bits
Example #25
0
 def Materials(self, val):
     if "Materials" not in self.root_tag:
         self.root_tag["Materials"] = nbt.TAG_String()
     self.root_tag["Materials"].value = val
Example #26
0
    def __init__(self, root_tag=None, filename=""):
        self.Width = 0
        self.Height = 0
        self.Length = 0
        self.Blocks = array([], "uint8")
        self.Data = array([], "uint8")
        self.Spawn = (0, 0, 0)
        self.filename = filename

        if root_tag:

            self.root_tag = root_tag
            mapTag = root_tag["Map"]
            self.Width = mapTag["Width"].value
            self.Length = mapTag["Length"].value
            self.Height = mapTag["Height"].value

            mapTag["Blocks"].value.shape = (self.Height, self.Length, self.Width)

            self.Blocks = swapaxes(mapTag["Blocks"].value, 0, 2)

            mapTag["Data"].value.shape = (self.Height, self.Length, self.Width)

            self.Data = swapaxes(mapTag["Data"].value, 0, 2)

            self.BlockLight = self.Data & 0xf

            self.Data >>= 4

            self.Spawn = [mapTag[Spawn][i].value for i in range(3)]

            if "Entities" not in root_tag:
                root_tag["Entities"] = nbt.TAG_List()
            self.Entities = root_tag["Entities"]

            # xxx fixup Motion and Pos to match infdev format
            def numbersToDoubles(ent):
                for attr in "Motion", "Pos":
                    if attr in ent:
                        ent[attr] = nbt.TAG_List([nbt.TAG_Double(t.value) for t in ent[attr]])

            for ent in self.Entities:
                numbersToDoubles(ent)

            if "TileEntities" not in root_tag:
                root_tag["TileEntities"] = nbt.TAG_List()
            self.TileEntities = root_tag["TileEntities"]
            # xxx fixup TileEntities positions to match infdev format
            for te in self.TileEntities:
                pos = te["Pos"].value

                (x, y, z) = self.decodePos(pos)

                TileEntity.setpos(te, (x, y, z))

            localPlayerList = [tag for tag in root_tag["Entities"] if tag['id'].value == 'LocalPlayer']
            if len(localPlayerList) == 0:  # omen doesn't make a player entity
                playerTag = nbt.TAG_Compound()
                playerTag['id'] = nbt.TAG_String('LocalPlayer')
                playerTag['Pos'] = nbt.TAG_List([nbt.TAG_Float(0.), nbt.TAG_Float(64.), nbt.TAG_Float(0.)])
                playerTag['Rotation'] = nbt.TAG_List([nbt.TAG_Float(0.), nbt.TAG_Float(45.)])
                self.LocalPlayer = playerTag

            else:
                self.LocalPlayer = localPlayerList[0]

        else:
            log.info(u"Creating new Indev levels is not yet implemented.!")
            raise ValueError("Can't do that yet")
Example #27
0
    def __init__(self, root_tag=None, filename=""):
        self.Width = 0
        self.Height = 0
        self.Length = 0
        self.Blocks = array([], uint8)
        self.Data = array([], uint8)
        self.Spawn = (0, 0, 0)
        self.filename = filename

        if root_tag:

            self.root_tag = root_tag
            mapTag = root_tag[Map]
            self.Width = mapTag[Width].value
            self.Length = mapTag[Length].value
            self.Height = mapTag[Height].value

            mapTag[Blocks].value.shape = (self.Height, self.Length, self.Width)

            self.Blocks = swapaxes(mapTag[Blocks].value, 0, 2)

            mapTag[Data].value.shape = (self.Height, self.Length, self.Width)

            self.Data = swapaxes(mapTag[Data].value, 0, 2)

            self.BlockLight = self.Data & 0xf

            self.Data >>= 4

            self.Spawn = [mapTag[Spawn][i].value for i in range(3)]

            if not Entities in root_tag:
                root_tag[Entities] = nbt.TAG_List()
            self.Entities = root_tag[Entities]

            # xxx fixup Motion and Pos to match infdev format
            def numbersToDoubles(ent):
                for attr in "Motion", "Pos":
                    if attr in ent:
                        ent[attr] = nbt.TAG_List(
                            [nbt.TAG_Double(t.value) for t in ent[attr]])

            for ent in self.Entities:
                numbersToDoubles(ent)

            if not TileEntities in root_tag:
                root_tag[TileEntities] = nbt.TAG_List()
            self.TileEntities = root_tag[TileEntities]
            # xxx fixup TileEntities positions to match infdev format
            for te in self.TileEntities:
                pos = te["Pos"].value

                (x, y, z) = self.decodePos(pos)

                TileEntity.setpos(te, (x, y, z))

            if len(
                    filter(lambda x: x['id'].value == 'LocalPlayer',
                           root_tag[Entities])
            ) == 0:  # omen doesn't make a player entity
                p = nbt.TAG_Compound()
                p['id'] = nbt.TAG_String('LocalPlayer')
                p['Pos'] = nbt.TAG_List(
                    [nbt.TAG_Float(0.),
                     nbt.TAG_Float(64.),
                     nbt.TAG_Float(0.)])
                p['Rotation'] = nbt.TAG_List(
                    [nbt.TAG_Float(0.), nbt.TAG_Float(45.)])

                root_tag[Entities].append(p)
                # self.saveInPlace()

        else:
            info(u"Creating new Indev levels is not yet implemented.!")
            raise ValueError("Can't do that yet")
Example #28
0
 def LevelName(self, name):
     self.root_tag["LevelName"] = nbt.TAG_String(value=name)
     with open(os.path.join(self.worldFile.path, "levelname.txt"),
               'w') as f:
         f.write(name)
Example #29
0
    def save(self, filename=""):
        structure_tag = nbt.TAG_Compound()
        blocks_tag = nbt.TAG_List()
        palette_tag = nbt.TAG_List()
        entities_tag = nbt.TAG_List()

        palette = []

        if not self._author:
            self._author = "MCEdit-Unified v{}".format(RELEASE_TAG)

        structure_tag["author"] = nbt.TAG_String(self._author)
        if self._version:
            structure_tag["DataVersion"] = nbt.TAG_Int(self.Version)
        else:
            structure_tag["DataVersion"] = nbt.TAG_Int(
                self.SUPPORTED_VERSIONS[-1])

        structure_tag["size"] = nbt.TAG_List([
            nbt.TAG_Int(self.Size[0]),
            nbt.TAG_Int(self.Size[1]),
            nbt.TAG_Int(self.Size[2])
        ])

        blockstate_api = BlockstateAPI.material_map.get(
            self._mat, BlockstateAPI.material_map[alphaMaterials])
        for z in xrange(
                self._blocks.shape[2]
        ):  # For some reason, ndenumerate() didn't work, but this does
            for x in xrange(self._blocks.shape[0]):
                for y in xrange(self._blocks.shape[1]):

                    value = self._blocks[x, y, z]
                    name, properties = blockstate_api.idToBlockstate(*value)
                    blockstate = blockstate_api.stringifyBlockstate(
                        name, properties)

                    #if blockstate not in index_table:
                    #    index_table[blockstate] = len(index_table)
                    #index = index_table[blockstate]
                    if blockstate not in palette:
                        palette.append(blockstate)
                    index = palette.index(blockstate)

                    block = nbt.TAG_Compound()
                    block["state"] = nbt.TAG_Int(index)
                    block["pos"] = nbt.TAG_List(
                        [nbt.TAG_Int(x),
                         nbt.TAG_Int(y),
                         nbt.TAG_Int(z)])

                    if self._tile_entities[x, y, z]:
                        block["nbt"] = self._tile_entities[x, y, z]

                    blocks_tag.append(block)
        structure_tag["blocks"] = blocks_tag

        for blockstate in palette:
            name, properties = blockstate_api.deStringifyBlockstate(blockstate)

            state = nbt.TAG_Compound()
            state["Name"] = nbt.TAG_String(name)

            if properties:
                props = nbt.TAG_Compound()
                for (key, value) in properties.iteritems():
                    props[key] = nbt.TAG_String(value)
                state["Properties"] = props

            palette_tag.insert(palette.index(blockstate), state)
        structure_tag["palette"] = palette_tag

        for e in self._entities:
            entity = nbt.TAG_Compound()
            pos = e["Pos"]
            entity["pos"] = pos
            entity["nbt"] = e
            blockPos = nbt.TAG_List()
            for coord in pos:
                blockPos.append(nbt.TAG_Int(math.floor(coord.value)))
            entity["blockPos"] = blockPos

            entities_tag.append(entity)

        structure_tag["entities"] = entities_tag
        structure_tag.save(filename)
Example #30
0
    def __init__(self, shape=None, root_tag=None, filename=None, mats='Alpha'):
        """ shape is (x,y,z) for a new level's shape.  if none, takes
        root_tag as a TAG_Compound for an existing schematic file.  if
        none, tries to read the tag from filename.  if none, results
        are undefined. materials can be a MCMaterials instance, or one of
        "Classic", "Alpha", "Pocket" to indicate allowable blocks. The default
        is Alpha.

        block coordinate order in the file is y,z,x to use the same code as classic/indev levels.
        in hindsight, this was a completely arbitrary decision.

        the Entities and TileEntities are nbt.TAG_List objects containing TAG_Compounds.
        this makes it easy to copy entities without knowing about their insides.

        rotateLeft swaps the axes of the different arrays.  because of this, the Width, Height, and Length
        reflect the current dimensions of the schematic rather than the ones specified in the NBT structure.
        I'm not sure what happens when I try to re-save a rotated schematic.
        """

        # if(shape != None):
        #    self.setShape(shape)

        if filename:
            self.filename = filename
            if None is root_tag and os.path.exists(filename):
                root_tag = nbt.load(filename)
        else:
            self.filename = None

        if mats in namedMaterials:
            self.materials = namedMaterials[mats]
        else:
            assert (isinstance(mats, MCMaterials))
            self.materials = mats

        if root_tag:
            self.root_tag = root_tag
            if "Materials" in root_tag:
                self.materials = namedMaterials[self.Materials]
            else:
                root_tag["Materials"] = nbt.TAG_String(self.materials.name)
            self.shapeChunkData()

        else:
            assert shape is not None
            root_tag = nbt.TAG_Compound(name="Schematic")
            root_tag["Height"] = nbt.TAG_Short(shape[1])
            root_tag["Length"] = nbt.TAG_Short(shape[2])
            root_tag["Width"] = nbt.TAG_Short(shape[0])

            root_tag["Entities"] = nbt.TAG_List()
            root_tag["TileEntities"] = nbt.TAG_List()
            root_tag["Materials"] = nbt.TAG_String(self.materials.name)

            root_tag["Blocks"] = nbt.TAG_Byte_Array(
                zeros((shape[1], shape[2], shape[0]), uint8))
            root_tag["Data"] = nbt.TAG_Byte_Array(
                zeros((shape[1], shape[2], shape[0]), uint8))

            self.root_tag = root_tag

        self.packUnpack()
        self.root_tag["Data"].value &= 0xF  # discard high bits