Ejemplo n.º 1
0
            def fetch_chunk(cls, world_path: str, chunk_x: int,
                            chunk_z: int) -> Chunk:
                chunk_data, timestamp = chunkio.fetchChunk(
                    world_path, chunk_x, chunk_z)

                chunk_nbt = nbt.TAG_Compound.unpack(
                    Buffer(
                        zlib.decompress(b"".join(
                            [ord(c).to_bytes(1, "big") for c in chunk_data]))))

                return Chunk(chunk_nbt, int(timestamp))
Ejemplo n.º 2
0
    async def fetch_chunk(self, chunk_x: int, chunk_z: int) -> Chunk:
        key = (chunk_x, chunk_z)

        try:  # try to fetch chunk from cache
            return self._chunk_cache[key]
        except KeyError:
            pass

        try:  # try to fetch from disk
            return self.cache_chunk(
                await self.server.chunkio.fetch_chunk_async(self.path, *key),
                key)
        except FileNotFoundError:  # fall back to generate chunk
            sections = self.server.generator.generate_chunk(
                self.data["RandomSeed"], self.dimension, chunk_x, chunk_z)
            chunk = Chunk.new(chunk_x, chunk_z, sections, int(time.time()))

            return self.cache_chunk(chunk)
Ejemplo n.º 3
0
    def fetch_chunk(cls, world_path: str, chunk_x: int, chunk_z: int) -> Chunk:
        rx, ry = chunk_x // 32, chunk_z // 32
        region_path = os.path.join(world_path, "region", f"r.{rx}.{ry}.mca")

        if not os.path.isfile(region_path):
            raise FileNotFoundError(region_path)

        loc_table_loc = cls.calc_offset(chunk_x, chunk_z)

        with open(region_path, "rb") as region_file:
            region_file.seek(loc_table_loc)

            offset, length = cls.find_chunk(region_file.read(4))

            region_file.seek(loc_table_loc + 4096)
            timestamp = struct.unpack(">i", region_file.read(4))

            region_file.seek(offset + 5)
            return Chunk(
                nbt.TAG_Compound.unpack(
                    Buffer(zlib.decompress(region_file.read(length - 5)))),
                timestamp)
Ejemplo n.º 4
0
    def generate_chunk(seed: int, dimension: str, chunk_x: int,
                       chunk_z: int) -> Chunk:
        chunk = Chunk.new(chunk_x, chunk_z, int(time.time()))

        chunk.sections[0] = ChunkSection.new(0, DirectPalette)
        palette = chunk.sections[0].palette

        if dimension == "minecraft:overworld":
            chunk.sections[0].block_states[0] = palette.encode(
                "minecraft:bedrock")
            chunk.sections[0].block_states[1:3] = palette.encode(
                "minecraft:dirt")
            chunk.sections[0].block_states[3] = palette.encode(
                "minecraft:grass_block", {"snowy": "false"})

            chunk.sections[0].block_light[0:4] = 0

            chunk.sections[0].sky_light[0:3] = 0
            chunk.sections[0].sky_light[3:] = 15
        elif dimension == "minecraft:nether":
            chunk.sections[0].block_states[0] = palette.encode(
                "minecraft:bedrock")
            chunk.sections[0].block_states[1:4] = palette.encode(
                "minecraft:netherrack")

            chunk.sections[0].block_light[0:4] = 0
            chunk.sections[0].sky_light[4:] = 7
        elif dimension == "minecraft:the_end":
            chunk.sections[0].block_states[0:4] = palette.encode(
                "minecraft:end_stone")

            chunk.sections[0].block_light[0:4] = 0
            chunk.sections[0].sky_light[4:] = 0
        else:
            raise ValueError(f"Unsupported dimension: {dimension}")

        return chunk
Ejemplo n.º 5
0
    def pack_chunk_light(cls, chunk: Chunk) -> bytes:
        out = cls.pack_varint(chunk.x) + cls.pack_varint(chunk.z) + cls.pack("?", True)

        sky_light_mask = 0
        block_light_mask = 0
        empty_sky_light_mask = 0
        empty_block_light_mask = 0

        sky_light_arrays = []
        block_light_arrays = []

        for section_y in range(-1, 17, 1):
            section = chunk.get(section_y)

            if section is None:
                continue

            print("Section y/index:", section_y)

            if section.sky_light is not None and len(section.sky_light.nonzero()) > 0:
                sky_light_mask |= 1 << section_y

                sky_light_array = b""

                for y in range(16):
                    for z in range(16):
                        for x in range(0, 16, 2):
                            sky_light_array += cls.pack(
                                "B",
                                (section.sky_light[y][z][x] << 4)
                                | (section.sky_light[y][z][x + 1]),
                            )

                print("Sky light array length:", len(sky_light_array))

                sky_light_arrays.append(cls.pack_varint(len(sky_light_array)) + sky_light_array)

            if section.block_light is not None and len(section.block_light.nonzero()) > 0:
                block_light_mask |= 1 << section_y

                block_light_array = b""

                for y in range(16):
                    for z in range(16):
                        for x in range(0, 16, 2):
                            block_light_array += cls.pack(
                                "B",
                                (section.block_light[y][z][x] << 4)
                                | (section.block_light[y][z][x + 1]),
                            )

                print("Block light array length:", len(block_light_array))

                block_light_arrays.append(
                    cls.pack_varint(len(block_light_array)) + block_light_array
                )

        print("Sky light mask:", sky_light_mask)
        print("Block light mask:", block_light_mask)

        out = (
            cls.pack_varint(sky_light_mask)
            + cls.pack_varint(block_light_mask)
            + cls.pack_varint(empty_sky_light_mask)
            + cls.pack_varint(empty_block_light_mask)
            + b"".join(sky_light_arrays)
            + b"".join(block_light_arrays)
        )

        return out  # [:len(out) - 4095]