Skip to content

Commit e78f426

Browse files
committed
wtf
1 parent 2f4aa8a commit e78f426

File tree

6 files changed

+52
-40
lines changed

6 files changed

+52
-40
lines changed

src/bin/src/systems/chunk_fetcher.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::errors::BinaryError;
22
use crate::systems::definition::System;
33
use async_trait::async_trait;
44
use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
5+
use ferrumc_core::chunks::chunk_receiver::ChunkSendState::{Fetching, Sending};
56
use ferrumc_state::GlobalState;
67
use ferrumc_world::chunk_format::Chunk;
78
use ferrumc_world::vanilla_chunk_format::BlockData;
@@ -43,7 +44,7 @@ impl System for ChunkFetcher {
4344
let mut copied_chunks = HashMap::new();
4445
for chunk in chunk_recv.needed_chunks.iter() {
4546
let (key, chunk) = chunk;
46-
if chunk.is_none() {
47+
if let Fetching = chunk {
4748
copied_chunks.insert(key.clone(), None);
4849
}
4950
}
@@ -85,8 +86,10 @@ impl System for ChunkFetcher {
8586
trace!("A player disconnected before we could get the ChunkReceiver");
8687
return Ok(());
8788
};
88-
for (key, chunk) in copied_chunks.iter() {
89-
chunk_recv.needed_chunks.insert(key.clone(), chunk.clone());
89+
for (key, chunk) in copied_chunks {
90+
if let Some(chunk) = chunk {
91+
chunk_recv.needed_chunks.insert(key.clone(), Sending(chunk));
92+
}
9093
}
9194
}
9295
Ok(())

src/bin/src/systems/chunk_sender.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::systems::definition::System;
22
use async_trait::async_trait;
33
use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
4+
use ferrumc_core::chunks::chunk_receiver::ChunkSendState::{Sending, Sent};
45
use ferrumc_ecs::errors::ECSError;
56
use ferrumc_net::connection::StreamWriter;
67
use ferrumc_net::packets::outgoing::chunk_and_light_data::ChunkAndLightData;
@@ -14,7 +15,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
1415
use std::sync::Arc;
1516
use std::time::Duration;
1617
use tokio::task::JoinSet;
17-
use tracing::{error, info, trace};
18+
use tracing::{debug, error, info, trace};
1819

1920
pub(super) struct ChunkSenderSystem {
2021
pub stop: AtomicBool,
@@ -55,7 +56,6 @@ impl System for ChunkSenderSystem {
5556
}
5657
// We can't delete from the map while iterating, so we collect the keys to drop
5758
// and then drop them after sending the chunks
58-
let mut to_drop = Vec::new();
5959
{
6060
let Ok(chunk_recv) = state.universe.get::<ChunkReceiver>(eid) else {
6161
trace!("A player disconnected before we could get the ChunkReceiver");
@@ -75,28 +75,20 @@ impl System for ChunkSenderSystem {
7575
.expect("ChunkReceiver not found");
7676
trace!("Got chunk_recv 3 for sender");
7777
for (key, chunk) in chunk_recv.needed_chunks.iter_mut() {
78-
if let Some(chunk) = chunk {
79-
to_drop.push(key.clone());
80-
match ChunkAndLightData::from_chunk(&chunk.clone()) {
78+
if let Sending(confirmed_chunk) = chunk {
79+
match ChunkAndLightData::from_chunk(&confirmed_chunk.clone()) {
8180
Ok(packet) => {
81+
debug!("Queuing chunk for sending");
8282
packets.push(packet);
8383
}
8484
Err(e) => {
8585
error!("Error sending chunk: {:?}", e);
8686
}
8787
}
88+
*chunk = Sent;
8889
}
8990
}
90-
}
91-
{
92-
let Ok(mut chunk_recv) = state.universe.get_mut::<ChunkReceiver>(eid)
93-
else {
94-
trace!("A player disconnected before we could get the ChunkReceiver");
95-
return Ok(());
96-
};
97-
for key in to_drop {
98-
chunk_recv.needed_chunks.remove(&key);
99-
}
91+
chunk_recv.needed_chunks.retain(|_, v| v != &Sent);
10092
}
10193

10294
{

src/lib/core/src/chunks/chunk_receiver.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use tokio::time::Instant;
55

66
const VIEW_DISTANCE: i32 = 8;
77
pub struct ChunkReceiver {
8-
pub needed_chunks: HashMap<(i32, i32, String), Option<Chunk>>,
8+
pub needed_chunks: HashMap<(i32, i32, String), ChunkSendState>,
99
pub can_see: HashSet<(i32, i32, String)>,
1010
pub last_update: Instant,
1111
pub last_chunk: Option<(i32, i32, String)>,
@@ -19,6 +19,13 @@ impl Default for ChunkReceiver {
1919
}
2020
}
2121

22+
#[derive(Clone, Eq, PartialEq)]
23+
pub enum ChunkSendState {
24+
Fetching,
25+
Sending(Chunk),
26+
Sent,
27+
}
28+
2229
impl ChunkReceiver {
2330
pub fn new() -> Self {
2431
Self {
@@ -35,7 +42,7 @@ impl ChunkReceiver {
3542
if self.can_see.contains(&(x, z, dimension.clone())) {
3643
let entry = self.needed_chunks.get_mut(&(x, z, dimension.clone()));
3744
if let Some(entry) = entry {
38-
*entry = None;
45+
*entry = ChunkSendState::Fetching;
3946
}
4047
}
4148
}
@@ -49,7 +56,7 @@ impl ChunkReceiver {
4956
for z in last_chunk.1 - VIEW_DISTANCE..=last_chunk.1 + VIEW_DISTANCE {
5057
if !self.can_see.contains(&(x, z, last_chunk.2.clone())) {
5158
self.needed_chunks
52-
.insert((x, z, last_chunk.2.clone()), None);
59+
.insert((x, z, last_chunk.2.clone()), ChunkSendState::Fetching);
5360
}
5461
new_can_see.insert((x, z, last_chunk.2.clone()));
5562
}

src/lib/net/crates/codec/src/net_types/var_int.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use deepsize::DeepSizeOf;
88
use std::io::{Read, Write};
99
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
1010

11-
#[derive(Debug, Encode, Decode, Clone, DeepSizeOf)]
11+
#[derive(Debug, Encode, Decode, Clone, DeepSizeOf, Eq)]
1212
pub struct VarInt {
1313
/// The value of the VarInt.
1414
pub val: i32,

src/lib/net/src/packets/outgoing/chunk_and_light_data.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use ferrumc_net_codec::net_types::var_int::VarInt;
77
use ferrumc_world::chunk_format::{Chunk, Heightmaps, PaletteType};
88
use std::io::{Cursor, Write};
99
use std::ops::Not;
10-
use tracing::{debug, trace, warn};
10+
use tracing::{debug, warn};
1111

1212
const SECTIONS: usize = 24; // Number of sections, adjust for your Y range (-64 to 319)
1313

@@ -64,6 +64,7 @@ impl ChunkAndLightData {
6464
}
6565

6666
pub fn from_chunk(chunk: &Chunk) -> Result<Self, NetError> {
67+
debug!("Serializing chunk at {}, {}", chunk.x, chunk.z);
6768
let mut raw_data = Cursor::new(Vec::new());
6869
let mut sky_light_data = Vec::new();
6970
let mut block_light_data = Vec::new();
@@ -93,7 +94,7 @@ impl ChunkAndLightData {
9394

9495
match &section.block_states.block_data {
9596
PaletteType::Single(val) => {
96-
debug!("Single palette type: {:?}", (chunk.x, chunk.z));
97+
// debug!("Single palette type: {:?}", (chunk.x, chunk.z));
9798
raw_data.write_u8(0)?;
9899
val.write(&mut raw_data)?;
99100
VarInt::new(0).write(&mut raw_data)?;
@@ -103,7 +104,7 @@ impl ChunkAndLightData {
103104
data,
104105
palette,
105106
} => {
106-
debug!("Indirect palette type: {:?}", (chunk.x, chunk.z));
107+
// debug!("Indirect palette type: {:?}", (chunk.x, chunk.z));
107108
raw_data.write_u8(*bits_per_block)?;
108109
VarInt::new(palette.len() as i32).write(&mut raw_data)?;
109110
for palette_entry in palette {

src/lib/world/src/chunk_format.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ferrumc_macros::{NBTDeserialize, NBTSerialize};
99
use ferrumc_net_codec::net_types::var_int::VarInt;
1010
use lazy_static::lazy_static;
1111
use std::cmp::max;
12+
use std::collections::hash_map::Entry;
1213
use std::collections::HashMap;
1314
use std::io::Read;
1415
use tracing::{debug, error, warn};
@@ -40,7 +41,7 @@ lazy_static! {
4041
ID2BLOCK.iter().map(|(k, v)| (v.clone(), *k)).collect();
4142
}
4243

43-
#[derive(Encode, Decode, Clone, DeepSizeOf)]
44+
#[derive(Encode, Decode, Clone, DeepSizeOf, Eq, PartialEq)]
4445
// This is a placeholder for the actual chunk format
4546
pub struct Chunk {
4647
pub x: i32,
@@ -52,28 +53,29 @@ pub struct Chunk {
5253

5354
#[derive(Encode, Decode, NBTDeserialize, NBTSerialize, Clone, DeepSizeOf)]
5455
#[nbt(net_encode)]
56+
#[derive(Eq, PartialEq)]
5557
pub struct Heightmaps {
5658
#[nbt(rename = "MOTION_BLOCKING")]
5759
pub motion_blocking: Vec<i64>,
5860
#[nbt(rename = "WORLD_SURFACE")]
5961
pub world_surface: Vec<i64>,
6062
}
61-
#[derive(Encode, Decode, Clone, DeepSizeOf)]
63+
#[derive(Encode, Decode, Clone, DeepSizeOf, Eq, PartialEq)]
6264
pub struct Section {
6365
pub y: i8,
6466
pub block_states: BlockStates,
6567
pub biome_states: BiomeStates,
6668
pub block_light: Vec<u8>,
6769
pub sky_light: Vec<u8>,
6870
}
69-
#[derive(Encode, Decode, Clone, DeepSizeOf)]
71+
#[derive(Encode, Decode, Clone, DeepSizeOf, Eq, PartialEq)]
7072
pub struct BlockStates {
7173
pub non_air_blocks: u16,
7274
pub block_data: PaletteType,
7375
pub block_counts: HashMap<BlockData, i32>,
7476
}
7577

76-
#[derive(Encode, Decode, Clone, DeepSizeOf)]
78+
#[derive(Encode, Decode, Clone, DeepSizeOf, Eq, PartialEq)]
7779
pub enum PaletteType {
7880
Single(VarInt),
7981
Indirect {
@@ -87,7 +89,7 @@ pub enum PaletteType {
8789
},
8890
}
8991

90-
#[derive(Encode, Decode, Clone, DeepSizeOf)]
92+
#[derive(Encode, Decode, Clone, DeepSizeOf, Eq, PartialEq)]
9193
pub struct BiomeStates {
9294
pub bits_per_biome: u8,
9395
pub data: Vec<i64>,
@@ -127,7 +129,7 @@ impl VanillaChunk {
127129
let mut sections = Vec::new();
128130
for section in self.sections.as_ref().unwrap() {
129131
let y = section.y;
130-
let mut block_data: PaletteType;
132+
let block_data: PaletteType;
131133
let raw_block_data = section
132134
.block_states
133135
.as_ref()
@@ -277,7 +279,7 @@ impl BlockStates {
277279

278280
// Extract value at the current bit offset
279281
let value =
280-
read_nbit_i32(&long, *bits_per_block as usize, bit_offset as u32)?;
282+
read_nbit_i32(long, *bits_per_block as usize, bit_offset as u32)?;
281283
let max_int_value = (1 << new_bit_size) - 1;
282284
if value > max_int_value {
283285
return Err(InvalidBlockStateData(format!(
@@ -391,6 +393,7 @@ impl Chunk {
391393
.iter_mut()
392394
.find(|section| section.y == (y >> 4) as i8)
393395
.ok_or(WorldError::SectionOutOfBounds(y >> 4))?;
396+
// Do different things based on the palette type
394397
match &mut section.block_states.block_data {
395398
PaletteType::Single(val) => {
396399
debug!("Converting single block to indirect palette");
@@ -408,15 +411,17 @@ impl Chunk {
408411
palette,
409412
} => {
410413
let block_counts = &mut section.block_states.block_counts;
411-
match block_counts.get_mut(&old_block) {
412-
Some(e) => {
413-
if *e <= 0 {
414+
match block_counts.entry(old_block.clone()) {
415+
Entry::Occupied(mut occ_entry) => {
416+
let count = occ_entry.get_mut();
417+
if *count <= 0 {
414418
return Err(WorldError::InvalidBlock(old_block));
415419
}
416-
*e -= 1;
420+
*count -= 1;
417421
}
418-
None => {
422+
Entry::Vacant(empty_entry) => {
419423
warn!("Block not found in block counts: {:?}", old_block);
424+
empty_entry.insert(0);
420425
}
421426
}
422427
let block_id = BLOCK2ID
@@ -536,12 +541,16 @@ impl Chunk {
536541
}
537542

538543
pub fn new(x: i32, z: i32, dimension: String) -> Self {
539-
let mut sections: Vec<Section> = (0..24)
544+
let sections: Vec<Section> = (0..24)
540545
.map(|y| Section {
541546
y: y as i8,
542547
block_states: BlockStates {
543548
non_air_blocks: 0,
544-
block_data: PaletteType::Single(VarInt::from(0)),
549+
block_data: PaletteType::Indirect {
550+
bits_per_block: 4,
551+
data: vec![0; 256],
552+
palette: vec![VarInt::from(0)],
553+
},
545554
block_counts: HashMap::from([(BlockData::default(), 4096)]),
546555
},
547556
biome_states: BiomeStates {
@@ -579,7 +588,7 @@ impl Chunk {
579588
/// * `Err(WorldError)` - If an error occurs while setting the section.
580589
pub fn set_section(&mut self, section: u8, block: BlockData) -> Result<(), WorldError> {
581590
if let Some(section) = self.sections.get_mut(section as usize) {
582-
section.fill(block)
591+
section.fill(block.clone())
583592
} else {
584593
Err(WorldError::SectionOutOfBounds(section as i32))
585594
}

0 commit comments

Comments
 (0)