Skip to content

Commit 2797c97

Browse files
committed
Added delta movement packets, and also added file logging.
1 parent 05045b4 commit 2797c97

13 files changed

+230
-17
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ ferrumc-anvil = { path = "src/lib/adapters/anvil" }
8888
ferrumc-config = { path = "src/lib/utils/config" }
8989
ferrumc-core = { path = "src/lib/core" }
9090
ferrumc-ecs = { path = "src/lib/ecs" }
91-
ferrumc-events = { path = "src/lib/events" }
91+
ferrumc-events = { path = "src/lib/events"}
9292
ferrumc-general-purpose = { path = "src/lib/utils/general_purpose" }
9393
ferrumc-logging = { path = "src/lib/utils/logging" }
9494
ferrumc-macros = { path = "src/lib/derive_macros" }
@@ -115,6 +115,7 @@ async-trait = "0.1.82"
115115
# Logging
116116
tracing = "0.1.40"
117117
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
118+
tracing-appender = "0.2.3"
118119
log = "0.4.22"
119120
console-subscriber = "0.4.1"
120121

src/bin/Cargo.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ ferrumc-nbt = { workspace = true }
2727
ferrumc-general-purpose = { workspace = true }
2828
ferrumc-state = { workspace = true }
2929

30-
ctor = { workspace = true }
3130
parking_lot = { workspace = true, features = ["deadlock_detection"] }
3231
tracing = { workspace = true }
3332
tokio = { workspace = true }
34-
rayon = { workspace = true }
3533
futures = { workspace = true }
36-
serde_json = { workspace = true }
3734
async-trait = { workspace = true }
3835
clap = { workspace = true, features = ["derive"] }
36+
flate2 = { workspace = true }
37+
ctor = { workspace = true }
3938

4039

4140
[[bin]]

src/bin/src/packet_handlers/player/see_other_players.rs src/bin/src/packet_handlers/player/head_rot.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
use ferrumc_core::transform::grounded::OnGround;
2-
use ferrumc_core::transform::position::Position;
31
use ferrumc_core::transform::rotation::Rotation;
42
use ferrumc_macros::event_handler;
53
use ferrumc_net::errors::NetError;
64
use ferrumc_net::packets::outgoing::set_head_rotation::SetHeadRotationPacket;
7-
use ferrumc_net::packets::outgoing::teleport_entity::TeleportEntityPacket;
85
use ferrumc_net::packets::packet_events::TransformEvent;
96
use ferrumc_net::utils::broadcast::{broadcast, BroadcastOptions};
107
use ferrumc_net::utils::ecs_helpers::EntityExt;
@@ -18,16 +15,16 @@ async fn handle_player_move(
1815
) -> Result<TransformEvent, NetError> {
1916
let entity = event.conn_id;
2017

21-
let pos = entity.get::<Position>(&state)?;
18+
// let pos = entity.get::<Position>(&state)?;
2219
let rot = entity.get::<Rotation>(&state)?;
23-
let grounded = entity.get::<OnGround>(&state)?;
20+
// let grounded = entity.get::<OnGround>(&state)?;
2421

25-
let teleport_packet = TeleportEntityPacket::new(entity, &pos, &rot, grounded.0);
22+
// let teleport_packet = TeleportEntityPacket::new(entity, &pos, &rot, grounded.0);
2623
let head_rot_packet =
2724
SetHeadRotationPacket::new(entity as i32, NetAngle::from_degrees(rot.yaw as f64));
2825

2926
let start = std::time::Instant::now();
30-
broadcast(&teleport_packet, &state, BroadcastOptions::default().all()).await?;
27+
// broadcast(&teleport_packet, &state, BroadcastOptions::default().all()).await?;
3128
broadcast(&head_rot_packet, &state, BroadcastOptions::default().all()).await?;
3229

3330
tracing::trace!("broadcasting entity move took {:?}", start.elapsed());
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pub mod do_action;
2-
pub mod see_other_players;
2+
pub mod head_rot;
33
pub mod update_player_position;

src/bin/src/packet_handlers/player/update_player_position.rs

+87-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@ use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
22
use ferrumc_core::transform::grounded::OnGround;
33
use ferrumc_core::transform::position::Position;
44
use ferrumc_core::transform::rotation::Rotation;
5-
use ferrumc_macros::event_handler;
5+
use ferrumc_ecs::entities::Entity;
6+
use ferrumc_macros::{event_handler, NetEncode};
67
use ferrumc_net::errors::NetError;
8+
use ferrumc_net::packets::outgoing::teleport_entity::TeleportEntityPacket;
9+
use ferrumc_net::packets::outgoing::update_entity_position::UpdateEntityPositionPacket;
10+
use ferrumc_net::packets::outgoing::update_entity_position_and_rotation::UpdateEntityPositionAndRotationPacket;
11+
use ferrumc_net::packets::outgoing::update_entity_rotation::UpdateEntityRotationPacket;
712
use ferrumc_net::packets::packet_events::TransformEvent;
13+
use ferrumc_net::utils::broadcast::{broadcast, BroadcastOptions};
814
use ferrumc_net::utils::ecs_helpers::EntityExt;
15+
use ferrumc_net::NetResult;
916
use ferrumc_state::GlobalState;
1017
use tracing::trace;
1118

@@ -16,6 +23,9 @@ async fn handle_player_move(
1623
) -> Result<TransformEvent, NetError> {
1724
let conn_id = event.conn_id;
1825

26+
let mut delta_pos = None::<(i16, i16, i16)>;
27+
let mut new_rot = None::<Rotation>;
28+
1929
if let Some(ref new_position) = event.position {
2030
trace!("Getting chunk_recv 1 for player move");
2131
{
@@ -45,6 +55,12 @@ async fn handle_player_move(
4555
let mut position = conn_id.get_mut::<Position>(&state)?;
4656
trace!("Got position 1 for player move");
4757

58+
delta_pos = Some((
59+
((new_position.x * 4096.0) - (position.x * 4096.0)) as i16,
60+
((new_position.y * 4096.0) - (position.y * 4096.0)) as i16,
61+
((new_position.z * 4096.0) - (position.z * 4096.0)) as i16,
62+
));
63+
4864
*position = Position::new(new_position.x, new_position.y, new_position.z);
4965
}
5066

@@ -53,7 +69,10 @@ async fn handle_player_move(
5369
let mut rotation = conn_id.get_mut::<Rotation>(&state)?;
5470
trace!("Got rotation 1 for player move");
5571

56-
*rotation = Rotation::new(new_rotation.yaw, new_rotation.pitch);
72+
let new_rotation = Rotation::new(new_rotation.yaw, new_rotation.pitch);
73+
new_rot = Some(new_rotation.clone());
74+
75+
*rotation = new_rotation;
5776
}
5877

5978
if let Some(new_grounded) = event.on_ground {
@@ -64,5 +83,71 @@ async fn handle_player_move(
6483
*on_ground = OnGround(new_grounded);
6584
}
6685

86+
update_pos_for_all(conn_id, delta_pos, new_rot, &state).await?;
87+
6788
Ok(event)
6889
}
90+
91+
#[derive(NetEncode)]
92+
enum BroadcastMovementPacket {
93+
UpdateEntityPosition(UpdateEntityPositionPacket),
94+
UpdateEntityPositionAndRotation(UpdateEntityPositionAndRotationPacket),
95+
UpdateEntityRotation(UpdateEntityRotationPacket),
96+
TeleportEntity(TeleportEntityPacket),
97+
}
98+
99+
async fn update_pos_for_all(
100+
entity_id: Entity,
101+
delta_pos: Option<(i16, i16, i16)>,
102+
new_rot: Option<Rotation>,
103+
state: &GlobalState,
104+
) -> NetResult<()> {
105+
let is_grounded = entity_id.get::<OnGround>(state)?.0;
106+
107+
// If any delta of (x|y|z) exceeds 7.5, then it's "not recommended" to use this packet
108+
// As docs say: "If the movement exceeds these limits, Teleport Entity should be sent instead."
109+
// "should"????
110+
const MAX_DELTA: i16 = (7.5 * 4096f32) as i16;
111+
let delta_exceeds_threshold = match delta_pos {
112+
Some((delta_x, delta_y, delta_z)) => {
113+
delta_x.abs() > MAX_DELTA || delta_y.abs() > MAX_DELTA || delta_z.abs() > MAX_DELTA
114+
}
115+
None => false,
116+
};
117+
118+
let packet: BroadcastMovementPacket = if delta_exceeds_threshold {
119+
let pos = entity_id.get::<Position>(state)?;
120+
let rot = entity_id.get::<Rotation>(state)?;
121+
let grounded = entity_id.get::<OnGround>(state)?.0;
122+
123+
BroadcastMovementPacket::TeleportEntity(TeleportEntityPacket::new(
124+
entity_id, &pos, &rot, grounded,
125+
))
126+
} else {
127+
match (delta_pos, new_rot) {
128+
(Some(delta_pos), Some(new_rot)) => {
129+
BroadcastMovementPacket::UpdateEntityPositionAndRotation(
130+
UpdateEntityPositionAndRotationPacket::new(
131+
entity_id,
132+
delta_pos,
133+
&new_rot,
134+
is_grounded,
135+
),
136+
)
137+
}
138+
(Some(delta_pos), None) => BroadcastMovementPacket::UpdateEntityPosition(
139+
UpdateEntityPositionPacket::new(entity_id, delta_pos, is_grounded),
140+
),
141+
(None, Some(new_rot)) => BroadcastMovementPacket::UpdateEntityRotation(
142+
UpdateEntityRotationPacket::new(entity_id, &new_rot, is_grounded),
143+
),
144+
_ => {
145+
return Ok(());
146+
}
147+
}
148+
};
149+
150+
broadcast(&packet, state, BroadcastOptions::default().all()).await?;
151+
152+
Ok(())
153+
}

src/lib/events/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ ctor = { workspace = true}
1010
thiserror = { workspace = true }
1111
futures = { workspace = true }
1212
dashmap = { workspace = true }
13+
tracing = { workspace = true }

src/lib/events/src/infrastructure.rs

+6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ pub trait Event: Sized + Send + Sync + 'static {
7373
///
7474
/// Returns `Ok(())` if the execution succeeded. `Err(EventsError)` ifa listener failed.
7575
async fn trigger(event: Self::Data, state: Self::State) -> Result<(), Self::Error> {
76+
#[cfg(debug_assertions)]
77+
let start = std::time::Instant::now();
78+
7679
let listeners = EVENTS_LISTENERS
7780
.get(Self::name())
7881
.expect("Failed to find event listeners. Impossible;");
@@ -96,6 +99,9 @@ pub trait Event: Sized + Send + Sync + 'static {
9699
})
97100
.await?;
98101

102+
#[cfg(debug_assertions)]
103+
tracing::trace!("Event {} took {:?}", Self::name(), start.elapsed());
104+
99105
Ok(())
100106
}
101107

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

+6
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,11 @@ pub mod spawn_entity;
2424
pub mod entity_animation;
2525
pub mod entity_metadata;
2626
pub mod player_info_update;
27+
28+
// --------- Movement ----------
2729
pub mod set_head_rotation;
2830
pub mod teleport_entity;
31+
pub mod update_entity_position;
32+
pub mod update_entity_position_and_rotation;
33+
pub mod update_entity_rotation;
34+
// -----------------------------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use ferrumc_ecs::entities::Entity;
2+
use ferrumc_macros::{packet, NetEncode};
3+
use ferrumc_net_codec::net_types::var_int::VarInt;
4+
use std::io::Write;
5+
6+
#[derive(NetEncode)]
7+
#[packet(packet_id = 0x2E)]
8+
pub struct UpdateEntityPositionPacket {
9+
pub entity_id: VarInt,
10+
pub delta_x: i16,
11+
pub delta_y: i16,
12+
pub delta_z: i16,
13+
pub on_ground: bool,
14+
}
15+
16+
impl UpdateEntityPositionPacket {
17+
pub fn new(entity_id: Entity, delta_positions: (i16, i16, i16), on_ground: bool) -> Self {
18+
Self {
19+
entity_id: VarInt::new(entity_id as i32),
20+
delta_x: delta_positions.0,
21+
delta_y: delta_positions.1,
22+
delta_z: delta_positions.2,
23+
on_ground,
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use ferrumc_core::transform::rotation::Rotation;
2+
use ferrumc_ecs::entities::Entity;
3+
use ferrumc_macros::{packet, NetEncode};
4+
use ferrumc_net_codec::net_types::angle::NetAngle;
5+
use ferrumc_net_codec::net_types::var_int::VarInt;
6+
use std::io::Write;
7+
8+
#[derive(NetEncode)]
9+
#[packet(packet_id = 0x2F)]
10+
pub struct UpdateEntityPositionAndRotationPacket {
11+
pub entity_id: VarInt,
12+
pub delta_x: i16,
13+
pub delta_y: i16,
14+
pub delta_z: i16,
15+
pub yaw: NetAngle,
16+
pub pitch: NetAngle,
17+
pub on_ground: bool,
18+
}
19+
20+
impl UpdateEntityPositionAndRotationPacket {
21+
pub fn new(
22+
entity_id: Entity,
23+
delta_positions: (i16, i16, i16),
24+
new_rot: &Rotation,
25+
on_ground: bool,
26+
) -> Self {
27+
Self {
28+
entity_id: VarInt::new(entity_id as i32),
29+
delta_x: delta_positions.0,
30+
delta_y: delta_positions.1,
31+
delta_z: delta_positions.2,
32+
yaw: NetAngle::from_degrees(new_rot.yaw as f64),
33+
pitch: NetAngle::from_degrees(new_rot.pitch as f64),
34+
on_ground,
35+
}
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use ferrumc_core::transform::rotation::Rotation;
2+
use ferrumc_ecs::entities::Entity;
3+
use ferrumc_macros::{packet, NetEncode};
4+
use ferrumc_net_codec::net_types::angle::NetAngle;
5+
use ferrumc_net_codec::net_types::var_int::VarInt;
6+
use std::io::Write;
7+
8+
#[derive(NetEncode)]
9+
#[packet(packet_id = 0x30)]
10+
pub struct UpdateEntityRotationPacket {
11+
pub entity_id: VarInt,
12+
pub yaw: NetAngle,
13+
pub pitch: NetAngle,
14+
pub on_ground: bool,
15+
}
16+
impl UpdateEntityRotationPacket {
17+
pub fn new(entity_id: Entity, new_rot: &Rotation, on_ground: bool) -> Self {
18+
Self {
19+
entity_id: VarInt::new(entity_id as i32),
20+
yaw: NetAngle::from_degrees(new_rot.yaw as f64),
21+
pitch: NetAngle::from_degrees(new_rot.pitch as f64),
22+
on_ground,
23+
}
24+
}
25+
}

src/lib/utils/logging/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ edition = "2021"
66
[dependencies]
77
tracing = { workspace = true }
88
tracing-subscriber = { workspace = true }
9+
tracing-appender = { workspace = true }
910
tokio = { workspace = true }
1011
ferrumc-profiling = { workspace = true }
12+
ferrumc-general-purpose = { workspace = true }
1113
thiserror = { workspace = true }
1214
console-subscriber = { workspace = true }

src/lib/utils/logging/src/lib.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
pub mod errors;
22

3+
use ferrumc_general_purpose::paths::get_root_path;
34
use ferrumc_profiling::ProfilerTracingLayer;
45
use tracing::Level;
5-
use tracing_subscriber::fmt::Layer;
6+
use tracing_appender::rolling::{Rotation};
7+
use tracing_subscriber::fmt::{layer, Layer};
68
use tracing_subscriber::layer::SubscriberExt;
79
use tracing_subscriber::util::SubscriberInitExt;
810
use tracing_subscriber::EnvFilter;
@@ -11,10 +13,36 @@ pub fn init_logging(trace_level: Level) {
1113
//let console = console_subscriber::spawn();
1214
let env_filter = EnvFilter::from_default_env().add_directive(trace_level.into());
1315

16+
let is_verbose = trace_level > Level::INFO;
17+
18+
19+
let file_layer = {
20+
let file_appender = tracing_appender::rolling::Builder::new()
21+
.rotation(Rotation::DAILY)
22+
.filename_prefix("ferrumc")
23+
.filename_suffix("log.txt")
24+
.build( get_root_path().join("logs"))
25+
.unwrap();
26+
27+
if is_verbose {
28+
layer()
29+
.with_writer(file_appender)
30+
.with_ansi(false)
31+
} else {
32+
layer()
33+
.with_ansi(false)
34+
.with_writer(file_appender)
35+
.with_target(false)
36+
.with_thread_ids(false)
37+
.with_line_number(false)
38+
.with_file(false)
39+
}
40+
};
41+
1442
let mut fmt_layer = Layer::default();
1543

1644
// remove path from logs if log level is INFO
17-
if trace_level == Level::INFO {
45+
if !is_verbose {
1846
fmt_layer = fmt_layer
1947
.with_target(false)
2048
.with_thread_ids(false)
@@ -24,7 +52,7 @@ pub fn init_logging(trace_level: Level) {
2452
let profiler_layer = ProfilerTracingLayer;
2553

2654
tracing_subscriber::registry()
27-
// .with(console)
55+
.with(file_layer)
2856
.with(env_filter)
2957
.with(profiler_layer)
3058
.with(fmt_layer)

0 commit comments

Comments
 (0)