summaryrefslogtreecommitdiff
path: root/src/world.rs
blob: a500166d4e6f57974487fd82dba85764db3775d9 (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
75
76
77
78
79
80
81
82
83
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, 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(&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(())
    }
}