Ejemplo n.º 1
0
def saveFile(fName, data, savePolicy):
    if fName is None:
        return
    if os.path.exists(fName):
        r = ask("File already exists.\nClick 'OK' to choose one.")
        if r == 'OK':
            folder, name = os.path.split(fName)
            suffix = os.path.splitext(name)[-1][1:]
            fName = mcplatform.askSaveFile(folder, "Choose a NBT file...", name, 'Folder\0*.dat\0*.*\0\0', suffix)
        else:
            return
    if savePolicy == -1:
        if hasattr(data, 'name'):
            data.name = ""
    if not os.path.isdir(fName):
        if savePolicy <= 0:
            data.save(fName)
        elif savePolicy == 1:
            with littleEndianNBT():
                toSave = data.save(compressed=False)
                toSave = struct.Struct('<i').pack(4) + struct.Struct('<i').pack(len(toSave)) + toSave
                with open(fName, 'w') as f:
                    f.write(toSave)
    else:
        alert("The selected object is not a file.\nCan't save it.")
Ejemplo n.º 2
0
def saveFile(fName, data, savePolicy):
    if fName is None:
        return
    if os.path.exists(fName):
        r = ask("File already exists.\nClick 'OK' to choose one.")
        if r == 'OK':
            folder, name = os.path.split(fName)
            suffix = os.path.splitext(name)[-1][1:]
            fName = mcplatform.askSaveFile(folder, "Choose a NBT file...",
                                           name, 'Folder\0*.dat\0*.*\0\0',
                                           suffix)
        else:
            return
    if savePolicy == -1:
        if hasattr(data, 'name'):
            data.name = ""
    if not os.path.isdir(fName):
        if savePolicy <= 0:
            data.save(fName)
        elif savePolicy == 1:
            with littleEndianNBT():
                toSave = data.save(compressed=False)
                toSave = struct.Struct('<i').pack(4) + struct.Struct(
                    '<i').pack(len(toSave)) + toSave
                with open(fName, 'w') as f:
                    f.write(toSave)
    else:
        alert("The selected object is not a file.\nCan't save it.")
Ejemplo n.º 3
0
def CreateNewMapFilePE(level, number, colors):
    map = TAG_Compound()
    map["mapId"] = TAG_Long(number)
    map["parentMapId"] = TAG_Long(-1)
    map["decorations"] = TAG_List()
    map["dimension"] = TAG_Byte(0)
    map["fullyExplored"] = TAG_Byte(1)
    map["scale"] = TAG_Byte(4)
    map["height"] = TAG_Short(128)
    map["width"] = TAG_Short(128)
    map["xCenter"] = TAG_Int(2147483647)
    map["zCenter"] = TAG_Int(2147483647)
    map["colors"] = TAG_Byte_Array(colors)
    with level.worldFile.world_db() as db:
        wop = level.worldFile.writeOptions
        with nbt.littleEndianNBT():
            db.Put(wop, 'map_' + str(number), map.save(compressed=False))
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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."