from math import floor from ..networking.packets.clientbound.play import block_change_packet, chunk_data class ChunksManager: def __init__(self, data_manager): self.data = data_manager self.chunks = {} self.biomes = {} def handle_block(self, block_packet): self.set_block_at(block_packet.location.x, block_packet.location.y, block_packet.location.z, block_packet.block_state_id) #self.print_chunk(self.get_chunk(floor(block_packet.location.x/16), floor(block_packet.location.y/16), floor(block_packet.location.z/16)), block_packet.location.y%16) #print('Block %s at %s'%(blocks_states[block_packet.block_state_id], block_packet.location)) def handle_multiblock(self, multiblock_packet): for b in multiblock_packet.records: self.handle_block(b) def handle_chunk(self, chunk_packet): for i in chunk_packet.chunks: self.chunks[(chunk_packet.x, i, chunk_packet.z)] = chunk_packet.chunks[i] self.biomes[(chunk_packet.x, None, chunk_packet.z)] = chunk_packet.biomes # FIXME def register(self, connection): connection.register_packet_listener(self.handle_block, block_change_packet.BlockChangePacket) connection.register_packet_listener(self.handle_multiblock, block_change_packet.MultiBlockChangePacket) connection.register_packet_listener(self.handle_chunk, chunk_data.ChunkDataPacket) def get_chunk(self, x, y, z): index = (x, y, z) if not index in self.chunks: raise ChunkNotLoadedException(index) return self.chunks[index] def get_loaded_area(self, ignore_empty=False): first = next(iter(self.chunks.keys())) x0 = x1 = first[0] y0 = y1 = first[1] z0 = z1 = first[2] for k in self.chunks.keys(): if ignore_empty and self.chunks[k].empty: continue x0 = min(x0, k[0]) x1 = max(x1, k[0]) y0 = min(y0, k[1]) y1 = max(y1, k[1]) z0 = min(z0, k[2]) z1 = max(z1, k[2]) return ((x0,y0,z0),(x1,y1,z1)) def get_block_at(self, x, y, z): c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16)) return c.get_block_at(x%16, y%16, z%16) def set_block_at(self, x, y, z, block): c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16)) c.set_block_at(x%16, y%16, z%16, block) def print_chunk(self, chunk, y_slice): print("This is chunk %d %d %d at slice %d:"%(chunk.x, chunk.y, chunk.z, y_slice)) print("+%s+"%("-"*16)) for z in range(16): missing = [] print("|", end="") for x in range(16): sid = chunk.get_block_at(x, y_slice, z) bloc = self.data.blocks_states[sid] if bloc == "minecraft:air" or bloc == "minecraft:cave_air": c = " " elif bloc == "minecraft:grass_block" or bloc == "minecraft:dirt": c = "-" elif bloc == "minecraft:water": c = "~" elif bloc == "minecraft:lava": c = "!" elif bloc == "minecraft:bedrock": c = "_" elif bloc == "minecraft:stone": c = "X" else: missing.append(bloc) c = "?" print(c, end="") print("| %s"%(",".join(missing))) print("+%s+"%("-"*16)) if chunk.entities: print("Entities in slice: %s"%(", ".join([x['id'].decode() for x in chunk.entities]))) class ChunkNotLoadedException(Exception): def __str__(self): pos = self.args[0] return "Chunk at %d %d %d not loaded (yet?)"%(pos[0], pos[1], pos[2])