summaryrefslogtreecommitdiff
path: root/src/world.rs
blob: a1c7e113246f757cf18f65aece388aa96f8b0d3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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<Universe>,
}

impl DebugWorld {
    pub fn new(universe: Arc<Universe>) -> 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, 2)
        }
        let mut chunk_dat_serializer = BytesSerializer::default();
        for i in 0..(self.universe.max_world_section - self.universe.min_world_section) {
            let section = ChunkSection {
                block_count: if i < 4 { 16 * 16 * 16 } else { 0 },
                block_state: PalettedContainer { singular_value: if i < 4 { 1.into() } else { 0.into() } },
                biomes: PalettedContainer { singular_value: 0.into() },
            };
            chunk_dat_serializer.serialize_other(&section)?;
        }
        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(())
    }
}