Beispiel #1
0
def makeMaps(worldFolder, outputFolder, serverType, unlimitedTracking=False):
    nbtMapData = []
    if serverType == "bds":
        # open leveldb
        db = leveldb.open(os.path.join(worldFolder, "db"))

        # iterate over all the maps
        for a in tqdm(leveldb.iterate(db),
                      "leveldb map keys -> nbt".ljust(24),
                      bar_format="{l_bar}{bar}"):
            key = bytearray(a[0])
            if b"map" in key:
                # get extract an nbt object
                mapNbtIo = BytesIO(a[1])
                mapNbtFile = nbtlib.File.parse(mapNbtIo, byteorder="little")
                mapNbt = mapNbtFile.root
                mapId = int(mapNbt["mapId"])
                epoch = now
                nbtMapData.append({"epoch": epoch, "id": mapId, "nbt": mapNbt})

    elif serverType == "java":
        mapDatFiles = findMapFiles(worldFolder)
        for mapDatFile in tqdm(mapDatFiles,
                               "map_*.dat -> nbt".ljust(24),
                               bar_format="{l_bar}{bar}"):
            mapNbtFile = nbtlib.load(mapDatFile)
            mapNbt = mapNbtFile.root["data"]
            mapId = int(os.path.basename(mapDatFile)[4:-4])
            epoch = int(os.path.getmtime(mapDatFile))
            nbtMapData.append({"epoch": epoch, "id": mapId, "nbt": mapNbt})

    maps = []
    os.makedirs(outputFolder, exist_ok=True)
    mapPngs = getMapPngs(outputFolder)
    currentMapPngs = filterLatestMapPngsById(mapPngs)

    currentIdHashes = {(x.mapId, x.mapHash): x for x in currentMapPngs}
    currentIds = {x.mapId: x for x in currentMapPngs}

    for nbtMap in tqdm(nbtMapData,
                       "nbt -> png".ljust(24),
                       bar_format="{l_bar}{bar}"):
        mapId = nbtMap["id"]
        mapNbt = nbtMap["nbt"]
        mapEpoch = nbtMap["epoch"]
        try:
            mapUnlimitedTracking = mapNbt["unlimitedTracking"]
        except KeyError:
            mapUnlimitedTracking = False

        if mapUnlimitedTracking and not unlimitedTracking:
            continue
        scale = int(mapNbt["scale"])
        x = int(mapNbt["xCenter"])
        z = int(mapNbt["zCenter"])

        dimension = mapNbt["dimension"]
        mapColors = mapNbt["colors"]

        if type(dimension) == nbtlib.tag.Int:
            dimension = dimDict[mapNbt["dimension"]]
        elif type(dimension) == nbtlib.tag.Byte:
            dimension = dimDict[mapNbt["dimension"]]
        else:
            dimension = dimension.strip('"')

        try:
            mapBanners = mapNbt["banners"]
        except KeyError:
            mapBanners = []

        banners = []
        for banner in mapBanners:
            X = int(banner["Pos"]["X"])
            Y = int(banner["Pos"]["Y"])
            Z = int(banner["Pos"]["Z"])
            color = banner["Color"]

            try:
                name = json.loads(banner["Name"])["text"]

            except KeyError:
                name = ""

            bannerDict = {
                "X": X,
                "Y": Y,
                "Z": Z,
                "color": color,
                "name": name,
                "dimension": dimension
            }
            bannerTuple = BannerTuple(**bannerDict)
            banners.append(bannerTuple)

        frames = []
        # logging.debug(mapColors)

        if serverType == "bds":
            mapImage = Image.frombytes("RGBA", (128, 128),
                                       bytes([x % 256 for x in mapColors]),
                                       'raw')
        elif serverType == "java":
            colorTuples = [allColors[x % 256] for x in mapColors]
            mapImage = Image.new("RGBA", (128, 128))
            mapImage.putdata(colorTuples)

        mapHash = hashlib.md5(mapImage.tobytes()).hexdigest()

        # empty map
        if mapHash == "fcd6bcb56c1689fcef28b57c22475bad":
            continue

        if mapId not in currentIds:
            # brand new image
            logging.debug("%s is a new map", mapId)
            epoch = mapEpoch
        else:
            # changed image
            logging.debug("%s is already known", mapId)
            epoch = currentIds.get(mapId).epoch

            if (mapId, mapHash) not in currentIdHashes:
                epoch = now

        mapPng = MapPngTuple(mapId=mapId,
                             mapHash=mapHash,
                             epoch=epoch,
                             dimension=dimension,
                             x=x,
                             z=z,
                             scale=scale)

        if (mapId, mapHash) not in currentIdHashes:
            logging.debug("%s changed", mapId)
            mapImage = mapImage.resize((128 * 2**scale, ) * 2, Image.NEAREST)
            filename = mapPngFilenameFormat.format(**mapPng._asdict())

            mapImage.save(
                os.path.join(outputFolder, filename.replace(":", "@")))

        mapData = MapTuple(mapData=mapPng,
                           bannerData=banners,
                           frameData=frames)
        maps.append(mapData)

    logging.debug(maps)
    logging.info("Processed %s maps", len(maps))

    return maps
Beispiel #2
0
 def iterKeys(self, start=None, end=None):
   yield from ldb.iterate(self.db, start, end)