Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Block editing #150

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ hashbrown = "0.15.0"
tinyvec = "1.8.0"
dashmap = "6.1.0"
uuid = { version = "1.1", features = ["v4", "v3", "serde"] }
whirlwind = "0.1.1"

# Macros
lazy_static = "1.5.0"
Expand All @@ -164,12 +163,12 @@ libflate = "2.1.0"
flate2 = { version = "1.0.33", features = ["zlib"], default-features = false }
zstd = { version = "0.13.2" }
brotli = "7.0.0"
lzzzz = "1.1.0"
lzzzz = "2.0.0"
yazi = "0.2.0"
bzip2 = "0.4.1"
bzip2 = "0.5.0"

# Database
heed = "0.20.5"
heed = "0.21.0"
moka = "0.12.8"

# CLI
Expand All @@ -183,7 +182,6 @@ page_size = "0.6.0"
regex = "1.11.1"

# I/O
tempfile = "3.12.0"
memmap2 = "0.9.5"

# Benchmarking
Expand Down
8 changes: 4 additions & 4 deletions scripts/new_packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use std::sync::Arc;

#[derive(NetDecode)]
#[packet(packet_id = ++id++, state = "play")]
#[packet(packet_id = "++id++", state = "play")]
pub struct ++name++ {
}

Expand All @@ -24,7 +24,7 @@
use std::io::Write;

#[derive(NetEncode)]
#[packet(packet_id = ++id++)]
#[packet(packet_id = "++id++")]
pub struct ++name++ {}
"""

Expand All @@ -50,8 +50,8 @@ def to_camel_case(string) -> str:
packet_name = input("Packet name: ")
packets_dir = os.path.join(os.path.join(os.path.dirname(__file__), ".."), "src/lib/net/src/packets")

packet_id = input("Packet ID (formatted like 0x01): ")
packet_id = packet_id[:-2] + packet_id[-2:].upper()
packet_id = input(
"Packet ID (formatted as snake case, look on https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol if you need to get the id): ")

with open(f"{packets_dir}/{packet_type}/{to_snake_case(packet_name)}.rs", "x") as f:
if packet_type == "incoming":
Expand Down
1 change: 1 addition & 0 deletions src/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ async-trait = { workspace = true }
clap = { workspace = true, features = ["derive"] }
flate2 = { workspace = true }
ctor = { workspace = true }
rand = { workspace = true }


[[bin]]
Expand Down
1 change: 1 addition & 0 deletions src/bin/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![feature(portable_simd)]
#![forbid(unsafe_code)]
#![feature(random)]
extern crate core;

use crate::errors::BinaryError;
Expand Down
14 changes: 13 additions & 1 deletion src/bin/src/packet_handlers/login_process.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ferrumc_config::statics::{get_global_config, get_whitelist};
use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
use ferrumc_core::collisions::bounds::CollisionBounds;
use ferrumc_core::identity::player_identity::PlayerIdentity;
use ferrumc_core::transform::grounded::OnGround;
use ferrumc_core::transform::position::Position;
Expand Down Expand Up @@ -152,7 +153,18 @@ async fn handle_ack_finish_configuration(
.add_component::<Position>(entity_id, Position::default())?
.add_component::<Rotation>(entity_id, Rotation::default())?
.add_component::<OnGround>(entity_id, OnGround::default())?
.add_component::<ChunkReceiver>(entity_id, ChunkReceiver::default())?;
.add_component::<ChunkReceiver>(entity_id, ChunkReceiver::default())?
.add_component::<CollisionBounds>(
entity_id,
CollisionBounds {
x_offset_start: -0.3,
x_offset_end: 0.3,
y_offset_start: 0.0,
y_offset_end: 1.5,
z_offset_start: -0.3,
z_offset_end: 0.3,
},
)?;

let mut writer = state.universe.get_mut::<StreamWriter>(entity_id)?;

Expand Down
46 changes: 40 additions & 6 deletions src/bin/src/systems/chunk_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::errors::BinaryError;
use crate::systems::definition::System;
use async_trait::async_trait;
use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
use ferrumc_core::chunks::chunk_receiver::ChunkSendState::{Fetching, Sending};
use ferrumc_state::GlobalState;
use ferrumc_world::chunk_format::Chunk;
use ferrumc_world::vanilla_chunk_format::BlockData;
use std::collections::HashMap;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
Expand All @@ -13,6 +16,22 @@ pub struct ChunkFetcher {
stop: AtomicBool,
}

fn generate_chunk(x: i32, z: i32) -> Chunk {
let mut new_chunk = Chunk::new(x, z, "overworld".to_string());
for y in 0..10 {
new_chunk
.set_section(
y,
BlockData {
name: "minecraft:stone".to_string(),
properties: None,
},
)
.unwrap()
}
new_chunk
}

impl ChunkFetcher {
pub(crate) fn new() -> Self {
Self {
Expand Down Expand Up @@ -41,27 +60,42 @@ impl System for ChunkFetcher {
let mut copied_chunks = HashMap::new();
for chunk in chunk_recv.needed_chunks.iter() {
let (key, chunk) = chunk;
if chunk.is_none() {
if let Fetching = chunk {
copied_chunks.insert(key.clone(), None);
}
}
copied_chunks
};
// Fetch the chunks
for (key, chunk) in copied_chunks.iter_mut() {
let fetched_chunk =
state.world.load_chunk(key.0, key.1, &key.2.clone()).await?;
let fetched_chunk = if state
.world
.chunk_exists(key.0, key.1, &key.2.clone())
.await?
{
debug!("Chunk found, loading chunk");
state.world.load_chunk(key.0, key.1, &key.2.clone()).await?
} else {
debug!("Chunk not found, creating new chunk");
let new_chunk = generate_chunk(key.0, key.1);

state.world.save_chunk(new_chunk.clone()).await?;
new_chunk
};
*chunk = Some(fetched_chunk);
}
state.world.sync().await?;
// Insert the fetched chunks back into the component
{
let Ok(mut chunk_recv) = state.universe.get_mut::<ChunkReceiver>(eid)
else {
trace!("A player disconnected before we could get the ChunkReceiver");
return Ok(());
};
for (key, chunk) in copied_chunks.iter() {
chunk_recv.needed_chunks.insert(key.clone(), chunk.clone());
for (key, chunk) in copied_chunks {
if let Some(chunk) = chunk {
chunk_recv.needed_chunks.insert(key.clone(), Sending(chunk));
}
}
}
Ok(())
Expand All @@ -79,7 +113,7 @@ impl System for ChunkFetcher {
}
}
}
tokio::time::sleep(std::time::Duration::from_millis(5)).await;
tokio::time::sleep(std::time::Duration::from_millis(45)).await;
}
}

Expand Down
42 changes: 17 additions & 25 deletions src/bin/src/systems/chunk_sender.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::systems::definition::System;
use async_trait::async_trait;
use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
use ferrumc_core::chunks::chunk_receiver::ChunkSendState::{Sending, Sent};
use ferrumc_ecs::errors::ECSError;
use ferrumc_net::connection::StreamWriter;
use ferrumc_net::packets::outgoing::chunk_and_light_data::ChunkAndLightData;
Expand Down Expand Up @@ -55,7 +56,6 @@ impl System for ChunkSenderSystem {
}
// We can't delete from the map while iterating, so we collect the keys to drop
// and then drop them after sending the chunks
let mut to_drop = Vec::new();
{
let Ok(chunk_recv) = state.universe.get::<ChunkReceiver>(eid) else {
trace!("A player disconnected before we could get the ChunkReceiver");
Expand All @@ -67,38 +67,27 @@ impl System for ChunkSenderSystem {
centre_coords = (chunk.0, chunk.1);
}
}
let mut sent_chunks = 0;
{
let Ok(mut chunk_recv) = state.universe.get_mut::<ChunkReceiver>(eid)
else {
trace!("A player disconnected before we could get the ChunkReceiver");
return Ok(());
};
for possible_chunk in chunk_recv.needed_chunks.iter_mut() {
if let Some(chunk) = possible_chunk.1 {
let key = possible_chunk.0;
to_drop.push(key.clone());
match ChunkAndLightData::from_chunk(&chunk.clone()) {
trace!("Getting chunk_recv 3 for sender");
let mut chunk_recv = state
.universe
.get_mut::<ChunkReceiver>(eid)
.expect("ChunkReceiver not found");
trace!("Got chunk_recv 3 for sender");
for (_key, chunk) in chunk_recv.needed_chunks.iter_mut() {
if let Sending(confirmed_chunk) = chunk {
match ChunkAndLightData::from_chunk(&confirmed_chunk.clone()) {
Ok(packet) => {
packets.push(packet);
sent_chunks += 1;
}
Err(e) => {
error!("Error sending chunk: {:?}", e);
}
}
*chunk = Sent;
}
}
}
{
let Ok(mut chunk_recv) = state.universe.get_mut::<ChunkReceiver>(eid)
else {
trace!("A player disconnected before we could get the ChunkReceiver");
return Ok(());
};
for key in to_drop {
chunk_recv.needed_chunks.remove(&key);
}
chunk_recv.needed_chunks.retain(|_, v| v != &Sent);
}

{
Expand All @@ -123,14 +112,17 @@ impl System for ChunkSenderSystem {
{
error!("Error sending chunk: {:?}", e);
}
let mut count = 0;
for packet in packets {
if let Err(e) = conn.send_packet(packet, &NetEncodeOpts::WithLength) {
error!("Error sending chunk: {:?}", e);
} else {
count += 1;
}
}
if let Err(e) = conn.send_packet(
ChunkBatchFinish {
batch_size: VarInt::new(sent_chunks),
batch_size: VarInt::new(count),
},
&NetEncodeOpts::WithLength,
) {
Expand All @@ -154,7 +146,7 @@ impl System for ChunkSenderSystem {
}
}

tokio::time::sleep(Duration::from_millis(5)).await;
tokio::time::sleep(Duration::from_millis(45)).await;
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/lib/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ dashmap = { workspace = true }
ferrumc-world = { workspace = true }
tracing = { workspace = true }
log = "0.4.22"

[dev-dependencies]
criterion = { workspace = true }

[[bench]]
name = "core_bench"
harness = false
56 changes: 56 additions & 0 deletions src/lib/core/benches/collisions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use criterion::{black_box, Criterion};
use ferrumc_core::collisions::bounds::CollisionBounds;

pub fn bench_collides(c: &mut Criterion) {
let mut g = c.benchmark_group("collisions");
g.bench_function("Simple collides", |b| {
b.iter(|| {
let bounds1 = black_box(CollisionBounds {
x_offset_start: 0.0,
x_offset_end: 2.0,
y_offset_start: 0.0,
y_offset_end: 2.0,
z_offset_start: 0.0,
z_offset_end: 2.0,
});
let bounds2 = black_box(CollisionBounds {
x_offset_start: 1.0,
x_offset_end: 3.0,
y_offset_start: 1.0,
y_offset_end: 3.0,
z_offset_start: 1.0,
z_offset_end: 3.0,
});
bounds1.collides(
black_box((0.0, 0.0, 0.0)),
&bounds2,
black_box((0.0, 0.0, 0.0)),
);
})
});
g.bench_function("Complex collides", |b| {
b.iter(|| {
let bounds1 = black_box(CollisionBounds {
x_offset_start: 64.2,
x_offset_end: -8.4,
y_offset_start: -12.0,
y_offset_end: 16.3,
z_offset_start: 99.55,
z_offset_end: 100.999,
});
let bounds2 = black_box(CollisionBounds {
x_offset_start: 5.0,
x_offset_end: 6.0,
y_offset_start: 1.0,
y_offset_end: 0.0,
z_offset_start: 2.0,
z_offset_end: 3.0,
});
bounds1.collides(
black_box((12.0, 66.0, -5.0)),
&bounds2,
black_box((4444.0, -300.0, 0.1)),
);
})
});
}
9 changes: 9 additions & 0 deletions src/lib/core/benches/core_bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use criterion::{criterion_group, criterion_main, Criterion};
mod collisions;

fn bench(c: &mut Criterion) {
collisions::bench_collides(c);
}

criterion_group!(benches, bench);
criterion_main!(benches);
Loading