Skip to content

Commit

Permalink
Merge pull request #155 from ferrumc-rs/feature/see-other-players
Browse files Browse the repository at this point in the history
As long as you come back and fix the conditional viewing thing, LGTM
  • Loading branch information
ReCore-sys authored Jan 2, 2025
2 parents b99b139 + 61510e9 commit 1df4866
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 17 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ ferrumc-anvil = { path = "src/lib/adapters/anvil" }
ferrumc-config = { path = "src/lib/utils/config" }
ferrumc-core = { path = "src/lib/core" }
ferrumc-ecs = { path = "src/lib/ecs" }
ferrumc-events = { path = "src/lib/events" }
ferrumc-events = { path = "src/lib/events"}
ferrumc-general-purpose = { path = "src/lib/utils/general_purpose" }
ferrumc-logging = { path = "src/lib/utils/logging" }
ferrumc-macros = { path = "src/lib/derive_macros" }
Expand All @@ -115,6 +115,7 @@ async-trait = "0.1.82"
# Logging
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing-appender = "0.2.3"
log = "0.4.22"
console-subscriber = "0.4.1"

Expand Down
5 changes: 2 additions & 3 deletions src/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ ferrumc-nbt = { workspace = true }
ferrumc-general-purpose = { workspace = true }
ferrumc-state = { workspace = true }

ctor = { workspace = true }
parking_lot = { workspace = true, features = ["deadlock_detection"] }
tracing = { workspace = true }
tokio = { workspace = true }
rayon = { workspace = true }
futures = { workspace = true }
serde_json = { workspace = true }
async-trait = { workspace = true }
clap = { workspace = true, features = ["derive"] }
flate2 = { workspace = true }
ctor = { workspace = true }


[[bin]]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use ferrumc_core::transform::grounded::OnGround;
use ferrumc_core::transform::position::Position;
use ferrumc_core::transform::rotation::Rotation;
use ferrumc_macros::event_handler;
use ferrumc_net::errors::NetError;
use ferrumc_net::packets::outgoing::set_head_rotation::SetHeadRotationPacket;
use ferrumc_net::packets::outgoing::teleport_entity::TeleportEntityPacket;
use ferrumc_net::packets::packet_events::TransformEvent;
use ferrumc_net::utils::broadcast::{broadcast, BroadcastOptions};
use ferrumc_net::utils::ecs_helpers::EntityExt;
Expand All @@ -18,16 +15,16 @@ async fn handle_player_move(
) -> Result<TransformEvent, NetError> {
let entity = event.conn_id;

let pos = entity.get::<Position>(&state)?;
// let pos = entity.get::<Position>(&state)?;
let rot = entity.get::<Rotation>(&state)?;
let grounded = entity.get::<OnGround>(&state)?;
// let grounded = entity.get::<OnGround>(&state)?;

let teleport_packet = TeleportEntityPacket::new(entity, &pos, &rot, grounded.0);
// let teleport_packet = TeleportEntityPacket::new(entity, &pos, &rot, grounded.0);
let head_rot_packet =
SetHeadRotationPacket::new(entity as i32, NetAngle::from_degrees(rot.yaw as f64));

let start = std::time::Instant::now();
broadcast(&teleport_packet, &state, BroadcastOptions::default().all()).await?;
// broadcast(&teleport_packet, &state, BroadcastOptions::default().all()).await?;
broadcast(&head_rot_packet, &state, BroadcastOptions::default().all()).await?;

tracing::trace!("broadcasting entity move took {:?}", start.elapsed());
Expand Down
2 changes: 1 addition & 1 deletion src/bin/src/packet_handlers/player/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod do_action;
pub mod see_other_players;
pub mod head_rot;
pub mod update_player_position;
89 changes: 87 additions & 2 deletions src/bin/src/packet_handlers/player/update_player_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ use ferrumc_core::chunks::chunk_receiver::ChunkReceiver;
use ferrumc_core::transform::grounded::OnGround;
use ferrumc_core::transform::position::Position;
use ferrumc_core::transform::rotation::Rotation;
use ferrumc_macros::event_handler;
use ferrumc_ecs::entities::Entity;
use ferrumc_macros::{event_handler, NetEncode};
use ferrumc_net::errors::NetError;
use ferrumc_net::packets::outgoing::teleport_entity::TeleportEntityPacket;
use ferrumc_net::packets::outgoing::update_entity_position::UpdateEntityPositionPacket;
use ferrumc_net::packets::outgoing::update_entity_position_and_rotation::UpdateEntityPositionAndRotationPacket;
use ferrumc_net::packets::outgoing::update_entity_rotation::UpdateEntityRotationPacket;
use ferrumc_net::packets::packet_events::TransformEvent;
use ferrumc_net::utils::broadcast::{broadcast, BroadcastOptions};
use ferrumc_net::utils::ecs_helpers::EntityExt;
use ferrumc_net::NetResult;
use ferrumc_state::GlobalState;
use tracing::trace;

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

let mut delta_pos = None::<(i16, i16, i16)>;
let mut new_rot = None::<Rotation>;

if let Some(ref new_position) = event.position {
trace!("Getting chunk_recv 1 for player move");
{
Expand Down Expand Up @@ -45,6 +55,12 @@ async fn handle_player_move(
let mut position = conn_id.get_mut::<Position>(&state)?;
trace!("Got position 1 for player move");

delta_pos = Some((
((new_position.x * 4096.0) - (position.x * 4096.0)) as i16,
((new_position.y * 4096.0) - (position.y * 4096.0)) as i16,
((new_position.z * 4096.0) - (position.z * 4096.0)) as i16,
));

*position = Position::new(new_position.x, new_position.y, new_position.z);
}

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

*rotation = Rotation::new(new_rotation.yaw, new_rotation.pitch);
let new_rotation = Rotation::new(new_rotation.yaw, new_rotation.pitch);
new_rot = Some(new_rotation);

*rotation = new_rotation;
}

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

update_pos_for_all(conn_id, delta_pos, new_rot, &state).await?;

Ok(event)
}

#[derive(NetEncode)]
enum BroadcastMovementPacket {
UpdateEntityPosition(UpdateEntityPositionPacket),
UpdateEntityPositionAndRotation(UpdateEntityPositionAndRotationPacket),
UpdateEntityRotation(UpdateEntityRotationPacket),
TeleportEntity(TeleportEntityPacket),
}

async fn update_pos_for_all(
entity_id: Entity,
delta_pos: Option<(i16, i16, i16)>,
new_rot: Option<Rotation>,
state: &GlobalState,
) -> NetResult<()> {
let is_grounded = entity_id.get::<OnGround>(state)?.0;

// If any delta of (x|y|z) exceeds 7.5, then it's "not recommended" to use this packet
// As docs say: "If the movement exceeds these limits, Teleport Entity should be sent instead."
// "should"????
const MAX_DELTA: i16 = (7.5 * 4096f32) as i16;
let delta_exceeds_threshold = match delta_pos {
Some((delta_x, delta_y, delta_z)) => {
delta_x.abs() > MAX_DELTA || delta_y.abs() > MAX_DELTA || delta_z.abs() > MAX_DELTA
}
None => false,
};

let packet: BroadcastMovementPacket = if delta_exceeds_threshold {
let pos = entity_id.get::<Position>(state)?;
let rot = entity_id.get::<Rotation>(state)?;
let grounded = entity_id.get::<OnGround>(state)?.0;

BroadcastMovementPacket::TeleportEntity(TeleportEntityPacket::new(
entity_id, &pos, &rot, grounded,
))
} else {
match (delta_pos, new_rot) {
(Some(delta_pos), Some(new_rot)) => {
BroadcastMovementPacket::UpdateEntityPositionAndRotation(
UpdateEntityPositionAndRotationPacket::new(
entity_id,
delta_pos,
&new_rot,
is_grounded,
),
)
}
(Some(delta_pos), None) => BroadcastMovementPacket::UpdateEntityPosition(
UpdateEntityPositionPacket::new(entity_id, delta_pos, is_grounded),
),
(None, Some(new_rot)) => BroadcastMovementPacket::UpdateEntityRotation(
UpdateEntityRotationPacket::new(entity_id, &new_rot, is_grounded),
),
_ => {
return Ok(());
}
}
};

broadcast(&packet, state, BroadcastOptions::default().all()).await?;

Ok(())
}
1 change: 1 addition & 0 deletions src/lib/events/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ ctor = { workspace = true}
thiserror = { workspace = true }
futures = { workspace = true }
dashmap = { workspace = true }
tracing = { workspace = true }
6 changes: 6 additions & 0 deletions src/lib/events/src/infrastructure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub trait Event: Sized + Send + Sync + 'static {
///
/// Returns `Ok(())` if the execution succeeded. `Err(EventsError)` ifa listener failed.
async fn trigger(event: Self::Data, state: Self::State) -> Result<(), Self::Error> {
#[cfg(debug_assertions)]
let start = std::time::Instant::now();

let listeners = EVENTS_LISTENERS
.get(Self::name())
.expect("Failed to find event listeners. Impossible;");
Expand All @@ -96,6 +99,9 @@ pub trait Event: Sized + Send + Sync + 'static {
})
.await?;

#[cfg(debug_assertions)]
tracing::trace!("Event {} took {:?}", Self::name(), start.elapsed());

Ok(())
}

Expand Down
6 changes: 6 additions & 0 deletions src/lib/net/src/packets/outgoing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ pub mod spawn_entity;
pub mod entity_animation;
pub mod entity_metadata;
pub mod player_info_update;

// --------- Movement ----------
pub mod set_head_rotation;
pub mod teleport_entity;
pub mod update_entity_position;
pub mod update_entity_position_and_rotation;
pub mod update_entity_rotation;
// -----------------------------
26 changes: 26 additions & 0 deletions src/lib/net/src/packets/outgoing/update_entity_position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use ferrumc_ecs::entities::Entity;
use ferrumc_macros::{packet, NetEncode};
use ferrumc_net_codec::net_types::var_int::VarInt;
use std::io::Write;

#[derive(NetEncode)]
#[packet(packet_id = 0x2E)]
pub struct UpdateEntityPositionPacket {
pub entity_id: VarInt,
pub delta_x: i16,
pub delta_y: i16,
pub delta_z: i16,
pub on_ground: bool,
}

impl UpdateEntityPositionPacket {
pub fn new(entity_id: Entity, delta_positions: (i16, i16, i16), on_ground: bool) -> Self {
Self {
entity_id: VarInt::new(entity_id as i32),
delta_x: delta_positions.0,
delta_y: delta_positions.1,
delta_z: delta_positions.2,
on_ground,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use ferrumc_core::transform::rotation::Rotation;
use ferrumc_ecs::entities::Entity;
use ferrumc_macros::{packet, NetEncode};
use ferrumc_net_codec::net_types::angle::NetAngle;
use ferrumc_net_codec::net_types::var_int::VarInt;
use std::io::Write;

#[derive(NetEncode)]
#[packet(packet_id = 0x2F)]
pub struct UpdateEntityPositionAndRotationPacket {
pub entity_id: VarInt,
pub delta_x: i16,
pub delta_y: i16,
pub delta_z: i16,
pub yaw: NetAngle,
pub pitch: NetAngle,
pub on_ground: bool,
}

impl UpdateEntityPositionAndRotationPacket {
pub fn new(
entity_id: Entity,
delta_positions: (i16, i16, i16),
new_rot: &Rotation,
on_ground: bool,
) -> Self {
Self {
entity_id: VarInt::new(entity_id as i32),
delta_x: delta_positions.0,
delta_y: delta_positions.1,
delta_z: delta_positions.2,
yaw: NetAngle::from_degrees(new_rot.yaw as f64),
pitch: NetAngle::from_degrees(new_rot.pitch as f64),
on_ground,
}
}
}
25 changes: 25 additions & 0 deletions src/lib/net/src/packets/outgoing/update_entity_rotation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use ferrumc_core::transform::rotation::Rotation;
use ferrumc_ecs::entities::Entity;
use ferrumc_macros::{packet, NetEncode};
use ferrumc_net_codec::net_types::angle::NetAngle;
use ferrumc_net_codec::net_types::var_int::VarInt;
use std::io::Write;

#[derive(NetEncode)]
#[packet(packet_id = 0x30)]
pub struct UpdateEntityRotationPacket {
pub entity_id: VarInt,
pub yaw: NetAngle,
pub pitch: NetAngle,
pub on_ground: bool,
}
impl UpdateEntityRotationPacket {
pub fn new(entity_id: Entity, new_rot: &Rotation, on_ground: bool) -> Self {
Self {
entity_id: VarInt::new(entity_id as i32),
yaw: NetAngle::from_degrees(new_rot.yaw as f64),
pitch: NetAngle::from_degrees(new_rot.pitch as f64),
on_ground,
}
}
}
2 changes: 2 additions & 0 deletions src/lib/utils/logging/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ edition = "2021"
[dependencies]
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
tracing-appender = { workspace = true }
tokio = { workspace = true }
ferrumc-profiling = { workspace = true }
ferrumc-general-purpose = { workspace = true }
thiserror = { workspace = true }
console-subscriber = { workspace = true }
31 changes: 28 additions & 3 deletions src/lib/utils/logging/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
pub mod errors;

use ferrumc_general_purpose::paths::get_root_path;
use ferrumc_profiling::ProfilerTracingLayer;
use tracing::Level;
use tracing_subscriber::fmt::Layer;
use tracing_appender::rolling::Rotation;
use tracing_subscriber::fmt::{layer, Layer};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::EnvFilter;
Expand All @@ -11,10 +13,33 @@ pub fn init_logging(trace_level: Level) {
//let console = console_subscriber::spawn();
let env_filter = EnvFilter::from_default_env().add_directive(trace_level.into());

let is_verbose = trace_level > Level::INFO;

let file_layer = {
let file_appender = tracing_appender::rolling::Builder::new()
.rotation(Rotation::DAILY)
.filename_prefix("ferrumc")
.filename_suffix("log.txt")
.build(get_root_path().join("logs"))
.unwrap();

if is_verbose {
layer().with_writer(file_appender).with_ansi(false)
} else {
layer()
.with_ansi(false)
.with_writer(file_appender)
.with_target(false)
.with_thread_ids(false)
.with_line_number(false)
.with_file(false)
}
};

let mut fmt_layer = Layer::default();

// remove path from logs if log level is INFO
if trace_level == Level::INFO {
if !is_verbose {
fmt_layer = fmt_layer
.with_target(false)
.with_thread_ids(false)
Expand All @@ -24,7 +49,7 @@ pub fn init_logging(trace_level: Level) {
let profiler_layer = ProfilerTracingLayer;

tracing_subscriber::registry()
// .with(console)
.with(file_layer)
.with(env_filter)
.with(profiler_layer)
.with(fmt_layer)
Expand Down

0 comments on commit 1df4866

Please sign in to comment.