Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Skylight #105

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
03d2965
Tracing
DimitriTimoz Dec 23, 2023
a6df609
some instruments
DimitriTimoz Dec 24, 2023
9b6845e
tracy p64
DimitriTimoz Dec 24, 2023
8dad00d
enable tracing with feature
DimitriTimoz Dec 24, 2023
3dbd842
line feeding
DimitriTimoz Dec 24, 2023
7066adb
player tick span
DimitriTimoz Dec 24, 2023
5484b93
span in feature
DimitriTimoz Dec 24, 2023
7f22265
Stable shard system
DimitriTimoz Dec 24, 2023
7c0f2e9
Set air default item
DimitriTimoz Dec 24, 2023
0d0cb61
Set BitSet for chunData protocol
DimitriTimoz Dec 24, 2023
ff4f91a
Set Default NbtTag to null
DimitriTimoz Dec 24, 2023
5e0ed0f
Specify UpdateLight packet structure
DimitriTimoz Dec 24, 2023
782f974
Implement SectionLightData
DimitriTimoz Dec 24, 2023
3f2ac20
Implement LightPositionInChunkColumn
DimitriTimoz Dec 24, 2023
b0bfac4
Implement LightSystem
DimitriTimoz Dec 24, 2023
53fe27a
Implement Light structure
DimitriTimoz Dec 24, 2023
6540cf2
Implement LightPosition
DimitriTimoz Dec 24, 2023
ab8c09b
Set shards in Arc
DimitriTimoz Dec 24, 2023
9e0bfce
set Chunk & ChunkColumn accesible in light.rs
DimitriTimoz Dec 24, 2023
bb0b93d
Implement HeightMap
DimitriTimoz Dec 24, 2023
84a62dc
get NetworkChunkColumnData
DimitriTimoz Dec 24, 2023
c396c13
#[instrument(skip_all)]
DimitriTimoz Dec 25, 2023
3a9c583
Get chunks position in ordered circle
DimitriTimoz Dec 25, 2023
56bc96b
remove spaces
DimitriTimoz Dec 25, 2023
4adb08d
More tracing
DimitriTimoz Dec 25, 2023
aee0eca
Remove some tracing
DimitriTimoz Dec 25, 2023
a0e8696
optimize get_higher_skylight_filter_block
DimitriTimoz Dec 25, 2023
dd312aa
ensure loaded chunks
DimitriTimoz Dec 25, 2023
3774ac3
Pong
DimitriTimoz Dec 25, 2023
f7ed7c6
KeepAlive
DimitriTimoz Dec 25, 2023
1b1b79e
Load chunks in an ordered circle
DimitriTimoz Dec 25, 2023
6f8c374
Handshaking load
DimitriTimoz Dec 25, 2023
600395b
Update chunks
DimitriTimoz Dec 25, 2023
bfd88f7
Basic implementation of LightManager
DimitriTimoz Dec 25, 2023
309e9e8
init skylight when laoding chunk
DimitriTimoz Dec 25, 2023
9828270
add waring
DimitriTimoz Dec 25, 2023
113db1e
Implement ChunkColumn baisc init_independant_light
DimitriTimoz Dec 25, 2023
5fc9ba3
Add some light tests
DimitriTimoz Dec 25, 2023
738d87a
Fix warnings
DimitriTimoz Dec 25, 2023
2a27fdc
Fix handshaking
DimitriTimoz Dec 25, 2023
ee65367
Fix computing Chunk order
DimitriTimoz Dec 25, 2023
c78b761
pub use light
DimitriTimoz Dec 25, 2023
120efd5
Add a lot of light tests but it's not enought
DimitriTimoz Dec 25, 2023
7321b14
Chenge Max Chunks per request
DimitriTimoz Dec 28, 2023
d5d226b
Implement light getter & setter
DimitriTimoz Dec 28, 2023
05ceb8e
change test calls
DimitriTimoz Dec 28, 2023
23cc58b
Implement tests getters and setters
DimitriTimoz Dec 28, 2023
5ffcb51
Add positions tests
DimitriTimoz Dec 28, 2023
c28869a
Fix warnings
DimitriTimoz Dec 28, 2023
67ddbd4
To continue o nother device
DimitriTimoz Feb 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions minecraft-entities-derive/examples/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum AnyEntity {
Cow(Cow),
}

#[derive(Debug)]
pub struct Handler<T> {
uuid: Eid,
world: Arc<Mutex<()>>,
Expand Down
177 changes: 177 additions & 0 deletions minecraft-positions/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod shards;

use std::ops::AddAssign;

pub use minecraft_protocol::packets::Position as NetworkPosition;

#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
Expand Down Expand Up @@ -183,4 +185,179 @@ impl ChunkColumnPosition {
cz: self.cz,
}
}

pub fn get_circle_from_center(&self, radius: i32) -> Vec<ChunkColumnPosition> {
let mut chunks = Vec::new();
for x in 0..=radius {
for z in 0..=radius {
if x * x + z * z <= radius * radius {
chunks.push(ChunkColumnPosition {
cx: self.cx + x,
cz: self.cz + z,
});
chunks.push(ChunkColumnPosition {
cx: self.cx + x,
cz: self.cz - z,
});
chunks.push(ChunkColumnPosition {
cx: self.cx - x,
cz: self.cz + z,
});
chunks.push(ChunkColumnPosition {
cx: self.cx - x,
cz: self.cz - z,
});
}
}
}
chunks
}
}

#[derive(Debug, Clone)]
pub struct LightPositionInChunkColumn {
pub bx: u8,
pub y: usize,
pub bz: u8,
}

impl LightPositionInChunkColumn {
pub fn in_chunk(&self) -> BlockPositionInChunk {
BlockPositionInChunk {
bx: self.bx,
by: self.y.rem_euclid(16) as u8,
bz: self.bz,
}
}
}


impl From<BlockPositionInChunkColumn> for LightPositionInChunkColumn {
fn from(val: BlockPositionInChunkColumn) -> Self {
Self {
bx: val.bx,
y: (val.y + 64 + 16) as usize, // TODO: Use the world config
bz: val.bz,
}
}
}

#[derive(Debug, Clone)]
pub struct LightPosition {
pub x: i32,
pub y: usize,
pub z: i32,
}

impl From<LightPosition> for LightPositionInChunkColumn {
fn from(val: LightPosition) -> Self {
LightPositionInChunkColumn {
bx: val.x.rem_euclid(16) as u8,
y: val.y,
bz: val.z.rem_euclid(16) as u8,
}
}
}

impl From<LightPosition> for ChunkColumnPosition {
fn from(val: LightPosition) -> Self {
ChunkColumnPosition {
cx: val.x.div_euclid(16),
cz: val.z.div_euclid(16),
}
}
}

impl From<BlockPosition> for LightPosition {
fn from(val: BlockPosition) -> Self {
Self {
x: val.x,
y: (val.y + 64 + 16) as usize,
z: val.z,
}
}
}

impl From<LightPosition> for BlockPosition {
fn from(val: LightPosition) -> Self {
Self {
x: val.x,
y: val.y as i32 - 64 - 16,
z: val.z
}
}
}

impl LightPosition {
pub fn in_chunk(&self) -> BlockPositionInChunk {
BlockPositionInChunk {
bx: self.x.rem_euclid(16) as u8,
by: self.y.rem_euclid(16) as u8,
bz: self.z.rem_euclid(16) as u8,
}
}

pub fn get_neighbors(&self, n_chunk: usize) -> Vec<Self> {
let mut neighbors = Vec::new();
if self.y < ((n_chunk - 1) * 16) + 1 { // No block can be higher so no block can affect the light level
neighbors.push(LightPosition { x: self.x, y: self.y + 1, z: self.z });
}
neighbors.push(LightPosition { x: self.x - 1, y: self.y, z: self.z });
neighbors.push(LightPosition { x: self.x + 1, y: self.y, z: self.z });
neighbors.push(LightPosition { x: self.x, y: self.y, z: self.z - 1 });
neighbors.push(LightPosition { x: self.x, y: self.y, z: self.z + 1 });
if self.y > 0 {
neighbors.push(LightPosition { x: self.x, y: self.y - 1, z: self.z });
}
neighbors
}
}

impl PartialEq for LightPosition {
fn eq(&self, other: &Self) -> bool {
self.y == other.y
}
}

impl From<LightPosition> for BlockPositionInChunkColumn {
fn from(val: LightPosition) -> Self {
BlockPositionInChunkColumn {
bx: val.x.rem_euclid(16) as u8,
y: val.y as i32 - 64 - 16, // TODO: Use the world config
bz: val.x.rem_euclid(16) as u8,
}
}
}

impl AddAssign<usize> for LightPosition {
fn add_assign(&mut self, rhs: usize) {
self.y += rhs;
}
}

impl std::cmp::Eq for LightPosition {}

impl std::cmp::PartialOrd for LightPosition {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.y.cmp(&other.y))
}
}

impl std::cmp::Ord for LightPosition {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.y.cmp(&other.y)
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_light_positions_conversions() {
let light_position = LightPosition { x: 1, y: 1, z: 1 };
assert_eq!(light_position, LightPosition::from(BlockPosition::from(light_position.clone())));

let block_position = BlockPosition { x: 1, y: 1, z: 1 };
assert_eq!(block_position, BlockPosition::from(LightPosition::from(block_position.clone())));
}
}
5 changes: 4 additions & 1 deletion minecraft-positions/src/shards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::*;

impl ChunkColumnPosition {
pub fn shard(&self, shard_count: usize) -> usize {
(self.cx + self.cz).unsigned_abs() as usize % shard_count
const REGION_SIZE: i32 = 8;
let region_x = self.cx.div_euclid(REGION_SIZE);
let region_z = self.cz.div_euclid(REGION_SIZE);
(region_x + region_z).unsigned_abs() as usize % shard_count
}
}
6 changes: 2 additions & 4 deletions minecraft-protocol/build/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,7 @@ pub fn generate_block_enum(data: serde_json::Value) {
raw_harvest_tools.push(
block
.harvest_tools
.clone()
.into_iter()
.map(|(k, _v)| k)
.clone().into_keys()
.collect(),
);
let mut material = block
Expand Down Expand Up @@ -427,7 +425,7 @@ const AIR_BLOCKS: [bool; {max_value}] = {air_blocks:?};
default_state_ids = blocks.iter().map(|b| b.default_state).collect::<Vec<_>>(),
item_ids = blocks
.iter()
.map(|b| b.drops.get(0).copied().unwrap_or(0))
.map(|b| b.drops.first().copied().unwrap_or(0))
.collect::<Vec<_>>(),
materials = materials,
resistances = blocks.iter().map(|b| b.resistance).collect::<Vec<_>>(),
Expand Down
7 changes: 7 additions & 0 deletions minecraft-protocol/build/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ pub enum Item {{
{variants}
}}

impl Default for Item {{
#[inline]
fn default() -> Self {{
Item::Air
}}
}}

impl Item {{
#[inline]
pub fn from_id(id: u32) -> Option<Item> {{
Expand Down
11 changes: 6 additions & 5 deletions minecraft-protocol/src/components/chunk.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{nbt::NbtTag, *, components::blocks::BlockEntity};
use crate::{nbt::NbtTag, *, components::blocks::BlockEntity, packets::serializer::BitSet};

/// A complex data structure including block data and optionally entities of a chunk.
///
Expand All @@ -24,19 +24,19 @@ pub struct ChunkData<'a> {
/// BitSet containing bits for each section in the world + 2.
/// Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Sky Light array below.
/// The least significant bit is for blocks 16 blocks to 1 block below the min world height (one section below the world), while the most significant bit covers blocks 1 to 16 blocks above the max world height (one section above the world).
pub sky_light_mask: Array<'a, u64, VarInt>,
pub sky_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2.
/// Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Block Light array below.
/// The order of bits is the same as in Sky Light Mask.
pub block_light_mask: Array<'a, u64, VarInt>,
pub block_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2.
/// Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Block Light array below.
/// The order of bits is the same as in Sky Light Mask.
pub empty_sky_light_mask: Array<'a, u64, VarInt>,
pub empty_sky_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2.
/// Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Block Light array below.
/// The order of bits is the same as in Sky Light Mask.
pub empty_block_light_mask: Array<'a, u64, VarInt>,
pub empty_block_light_mask: BitSet<'a>,
/// Length should match the number of bits set in Sky Light Mask.
/// Each entry is an array of 2048 bytes.
/// There is 1 array for each bit set to true in the sky light mask, starting with the lowest value. Half a byte per light value. Indexed ((y<<8) | (z<<4) | x) / 2
Expand Down Expand Up @@ -221,6 +221,7 @@ impl Chunk {
Ok(chunks)
}

#[cfg_attr(feature = "tracing", instrument(skip(output)))]
pub fn into_data(chunks: Vec<Chunk>) -> Result<Vec<u8>, &'static str> {
let mut output = Vec::new();

Expand Down
3 changes: 2 additions & 1 deletion minecraft-protocol/src/nbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use arrays::*;
use compound::*;
use numbers::*;

#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Default)]
pub enum NbtTag {
#[default]
Null,
Byte(i8),
Short(i16),
Expand Down
16 changes: 14 additions & 2 deletions minecraft-protocol/src/packets/play_clientbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,20 @@ pub enum ClientboundPacket<'a> {

/// Updates light levels for a chunk
UpdateLight {
/// TODO: parse this
data: RawBytes<'a>,
/// Chunk coordinate (block coordinate divided by 16, rounded down)
cx: VarInt,
/// Chunk coordinate (block coordinate divided by 16, rounded down)
cz: VarInt,
/// BitSet containing bits for each section in the world + 2. Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Sky Light array below. The least significant bit is for blocks 16 blocks to 1 block below the min world height (one section below the world), while the most significant bit covers blocks 1 to 16 blocks above the max world height (one section above the world).
sky_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2. Each set bit indicates that the corresponding 16×16×16 chunk section has data in the Block Light array below. The order of bits is the same as in Sky Light Mask.
block_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2. Each set bit indicates that the corresponding 16×16×16 chunk section has all zeros for its Sky Light data. The order of bits is the same as in Sky Light Mask.
empty_sky_light_mask: BitSet<'a>,
/// BitSet containing bits for each section in the world + 2. Each set bit indicates that the corresponding 16×16×16 chunk section has all zeros for its Block Light data. The order of bits is the same as in Sky Light Mask.
empty_block_light_mask: BitSet<'a>,
sky_light_arrays: Array<'a, Array<'a, u8, VarInt>, VarInt>,
block_light_arrays: Array<'a, Array<'a, u8, VarInt>, VarInt>,
},

/// See [Protocol Encryption](https://wiki.vg/Protocol_Encryption) for information on logging in.
Expand Down
12 changes: 10 additions & 2 deletions minecraft-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ edition = "2021"

[dependencies]
env_logger = "0.10.0"
log = "0.4.20"
tokio = { version = "1.33.0", features = ["full"] }
futures = "0.3.29"
minecraft-protocol = { path="../minecraft-protocol" }
minecraft-protocol = { path="../minecraft-protocol"}
minecraft-positions = { path="../minecraft-positions" }
minecraft-entities-derive = { path="../minecraft-entities-derive" }
rand = "0.8.4"
tracy-client = { version = "0.16.4", features = ["enable"], optional = true}
tracing-tracy = { version = "0.10.4", features = ["enable", "system-tracing"], optional = true}
tracing-subscriber = "0.3.18"
log = "0.4.17"
tracing = { version = "0.1", features = ["attributes"] }

[features]
default = []
trace = ["tracy-client", "tracing-tracy" ]
2 changes: 2 additions & 0 deletions minecraft-server/src/entities/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use super::*;
init(self, server_msg_rcvr: BroadcastReceiver<ServerMessage>);
}
)]

#[derive(Debug)]
pub struct Entity {
pub position: Position,
pub velocity: Translation,
Expand Down
2 changes: 0 additions & 2 deletions minecraft-server/src/entities/monsters/zombies.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use minecraft_protocol::network;

use super::*;

#[derive(Default)]
Expand Down
Loading
Loading