use std::sync::Arc; use anyhow::Result; use async_trait::async_trait; use mcproto_rs::nbt::Tag; use mcproto_rs::Serializer; use mcproto_rs::types::{BytesSerializer, NamedNbtTag}; use mcproto_rs::v1_19_3::{BitSet, BlobArray, ChunkDataAndUpdateLightSpec, ChunkDataSpec, ChunkSection, LightDataSpec, Packet761, PalettedContainer}; use crate::convention::Universe; use crate::nbt; use crate::player::Player; #[async_trait] pub trait World { async fn send_chunk(&self, observer: &Player, chunk_x: i32, chunk_z: i32) -> Result<()>; } pub struct DebugWorld { universe: Arc, } impl DebugWorld { pub fn new(universe: Arc) -> DebugWorld { DebugWorld { universe } } } #[async_trait] impl World for DebugWorld { async fn send_chunk(&self, observer: &Player, chunk_x: i32, chunk_z: i32) -> Result<()> { let mut heightmap = BlobArray::new(9); for cx in 0..(16 * 16) { heightmap.set_entry(cx, 17) } let mut chunk_dat_serializer = BytesSerializer::default(); for i in 0..(self.universe.max_world_section - self.universe.min_world_section) { let mut blocks = BlobArray::new(15); // ceillog2(registrysize) for x in 0..16 { for y in 0..16 { for z in 0..16 { let idx = (((y * 16) + z) * 16) + x; blocks.set_entry(idx, if y == 15 { 2 } else { 1 }); } } } let section = ChunkSection { block_count: if i < 4 { 16 * 16 * 16 } else { 0 }, block_state: PalettedContainer::GlobalPalette(blocks), biomes: PalettedContainer::SingularValue(0.into()), }; chunk_dat_serializer.serialize_other(§ion)?; } let chunk_column_bytes = chunk_dat_serializer.into_bytes(); observer.send_packet(Packet761::ChunkDataAndUpdateLight(ChunkDataAndUpdateLightSpec { chunk_x, chunk_z, chunk_data: ChunkDataSpec { heightmaps: NamedNbtTag { root: nbt! { "MOTION_BLOCKING" :: (Tag::LongArray(heightmap.data.iter().map(|n| n.to_owned() as _).collect())), "WORLD_SURFACE" :: (Tag::LongArray(heightmap.data.iter().map(|n| n.to_owned() as _).collect())), }.with_name("root") }, buffer: chunk_column_bytes.into(), block_entities: vec![].into(), }, light_data: LightDataSpec { trust_edges: true, sky_y_mask: BitSet::empty(), block_y_mask: BitSet::empty(), empty_sky_y_mask: BitSet::empty(), empty_block_y_mask: BitSet::empty(), sky_updates: vec![].into(), block_updates: vec![].into(), }, }))?; Ok(()) } }