Пример #1
0
def test_4bits():
    region = EmptyRegion(0, 0)

    region.set_block(Block('minecraft', 'stone'), 0, 0, 0)
    region.set_block(Block('minecraft', 'dirt'), 1, 0, 0)
    region.set_block(Block('minecraft', 'oak_planks'), 2, 0, 0)
    region.set_block(Block('minecraft', 'sand'), 10, 7, 5)
    region.set_block(Block('minecraft', 'white_wool'), 8, 6, 0)
    region.set_block(Block('minecraft', 'bedrock'), 15, 15, 15)

    region = Region(region.save())

    for i, block in enumerate(region.get_chunk(0, 0).stream_blocks()):
        if i == 0:
            assert block.id == 'stone'
        elif i == 1:
            assert block.id == 'dirt'
        elif i == 2:
            assert block.id == 'oak_planks'
        elif i == coord_to_index(10, 7, 5):
            assert block.id == 'sand'
        elif i == coord_to_index(15, 15, 15):
            assert block.id == 'bedrock'
        elif i == coord_to_index(8, 6, 0):
            assert block.id == 'white_wool'
        else:
            assert block.id == 'air'
Пример #2
0
def test_from_filename(tmp_path):
    filename = tmp_path / "region.mca"
    contents = secrets.token_bytes()

    with open(filename, 'wb') as f:
        f.write(contents)

    region = Region.from_file(str(filename))
    assert region.data == contents
Пример #3
0
def __list_region_items(region: Region):
    region_items = dict()
    for x in range(32):
        for z in range(32):
            try:
                chunk_items = __list_chunk_items(region.get_chunk(x, z))
                region_items.update(chunk_items)
            except Exception:
                pass
    return region_items
Пример #4
0
def __list_world_items(region_names: [str]):
    world_items = dict()
    region_amount = str(len(region_names))
    scanned_regions = 0
    for region_name in region_names:
        region = Region.from_file(region_name)
        world_items.update(__list_region_items(region))
        scanned_regions += 1
        print(str(scanned_regions) + "/" + region_amount)
    return world_items
Пример #5
0
def test_index():
    region = EmptyRegion(0, 0)

    region.set_block(Block('minecraft', 'dirt'), 2, 0, 0)
    region.set_block(Block('minecraft', 'stone'), 3, 0, 0)
    blocks = 'stone,dirt,oak_planks,sand,bedrock'.split(',')
    for i, block in enumerate(blocks):
        region.set_block(Block('minecraft', block), i % 16, 0, i // 16)

    region = Region(region.save())

    for i, block in enumerate(region.get_chunk(0, 0).stream_blocks(index=2)):
        i += 2
        if i < len(blocks):
            assert block.id == blocks[i]
        else:
            assert block.id == 'air'
Пример #6
0
def main():
    print(f"Hello, Vespucci!")
    region = Region.from_file("./map_0.dat")
    print(f"Region loaded. Data length: {len(region.data)}")
    chunk = None
    for x in range(-1024, 1024):
        for z in range(-1024, 1024):
            try:
                chunk = region.get_chunk(x, z)
                print(f"Found chunk at x={x}, z={z}")
            except IndexError:
                pass
            except Exception as e:
                if "Unexistent" not in str(e):
                    raise
    if chunk is not None:
        print(f"Chunk loaded. {chunk}")
Пример #7
0
def test_index_5bits():
    region = EmptyRegion(0, 0)

    region.set_block(Block('minecraft', 'dirt'), 2, 0, 0)
    region.set_block(Block('minecraft', 'stone'), 3, 0, 0)
    blocks = 'stone,dirt,oak_planks,sand,bedrock,white_wool,red_wool,green_wool,sponge,awesome,these,dont,need,to,exist,foo,bar'.split(
        ',')
    for i, block in enumerate(blocks):
        region.set_block(Block('minecraft', block), i % 16, 0, i // 16)

    region = Region(region.save())

    for i, block in enumerate(region.get_chunk(0, 0).stream_blocks(index=17)):
        i += 17
        if i < len(blocks):
            assert block.id == blocks[i]
        else:
            assert block.id == 'air'
Пример #8
0
def test_5bits():
    from random import randint
    region = EmptyRegion(0, 0)

    blocks = 'stone,dirt,oak_planks,sand,bedrock,white_wool,red_wool,green_wool,sponge,awesome,these,dont,need,to,exist,foo,bar'.split(
        ',')
    positions = [(randint(0, 15), randint(0, 15), randint(0, 15))
                 for _ in range(len(blocks))]
    for block, pos in zip(blocks, positions):
        region.set_block(Block('minecraft', block), *pos)

    region = Region(region.save())

    for i, block in enumerate(region.get_chunk(0, 0).stream_blocks()):
        if block.id in blocks:
            assert coord_to_index(*positions[blocks.index(block.id)]) == i
        else:
            assert block.id == 'air'
def test_mixed_chunk_types():
    colors = ['red', 'orange', 'yellow', 'green']

    region = EmptyRegion(0, 0)

    chunk = EmptyChunk(0, 0)
    empty_chunk = EmptyChunk(1, 0)
    for i, color in enumerate(colors):
        chunk.set_block(Block(color), i, 0, 0)
        empty_chunk.set_block(Block(color), i, 0, 0)

    chunk = Chunk(chunk.save())

    region.add_chunk(chunk)
    region.add_chunk(empty_chunk)

    region = Region(region.save())

    for i in range(2):
        chunk = region.get_chunk(i, 0)
        for i, color in enumerate(colors):
            assert chunk.get_block(i, 0, 0).id == color
Пример #10
0
def test_from_filelike():
    contents = secrets.token_bytes()
    filelike = io.BytesIO(contents)

    region = Region.from_file(filelike)
    assert region.data == contents
Пример #11
0
 def place(self, region: anvil.Region, offset: Point = (0, 0, 0)) -> None:
     for point, block in self.items():
         region.set_block(block, point[0] + offset[0], point[1] + offset[1],
                          point[2] + offset[2])
Пример #12
0
def save_region(self, file=None, region: Region = None) -> bytes:
    """
    Returns the region as bytes with
    the anvil file format structure,
    aka the final ``.mca`` file.

    Parameters
    ----------
    file
        Either a path or a file object, if given region
        will be saved there.
    """
    # Store all the chunks data as zlib compressed nbt data
    chunks_data = []
    for chunk in self.chunks:
        if chunk is None:
            chunks_data.append(None)
            continue
        chunk_data = BytesIO()
        if isinstance(chunk, Chunk):
            nbt_data = nbt.NBTFile()
            nbt_data.tags.append(
                nbt.TAG_Int(name="DataVersion", value=chunk.version))
            nbt_data.tags.append(chunk.data)
        else:
            data = region.get_chunk(chunk.x, chunk.z).data
            nbt_data = chunk.save(data)
        nbt_data.write_file(buffer=chunk_data)
        chunk_data.seek(0)
        chunk_data = zlib.compress(chunk_data.read())
        chunks_data.append(chunk_data)

    # This is what is added after the location and timestamp header
    chunks_bytes = bytes()
    offsets = []
    for chunk in chunks_data:
        if chunk is None:
            offsets.append(None)
            continue
        # 4 bytes are for length, b"\x02" is the compression type which is 2 since its using zlib
        to_add = (len(chunk) + 1).to_bytes(4, "big") + b"\x02" + chunk

        # offset in 4KiB sectors
        sector_offset = len(chunks_bytes) // 4096
        sector_count = math.ceil(len(to_add) / 4096)
        offsets.append((sector_offset, sector_count))

        # Padding to be a multiple of 4KiB long
        to_add += bytes(4096 - (len(to_add) % 4096))
        chunks_bytes += to_add

    locations_header = bytes()
    for offset in offsets:
        # None means the chunk is not an actual chunk in the region
        # and will be 4 null bytes, which represents non-generated chunks to minecraft
        if offset is None:
            locations_header += bytes(4)
        else:
            # offset is (sector offset, sector count)
            locations_header += (offset[0] + 2).to_bytes(
                3, "big") + offset[1].to_bytes(1, "big")

    # Set them all as 0
    timestamps_header = bytes(4096)

    final = locations_header + timestamps_header + chunks_bytes

    # Pad file to be a multiple of 4KiB in size
    # as Minecraft only accepts region files that are like that
    final += bytes(4096 - (len(final) % 4096))
    assert len(final) % 4096 == 0  # just in case

    # Save to a file if it was given
    if file:
        if isinstance(file, str):
            with open(file, "wb") as f:
                f.write(final)
        else:
            file.write(final)
    return final