diff --git a/src/server/player/context.rs b/src/server/player/context.rs index 45bd010..e914c80 100644 --- a/src/server/player/context.rs +++ b/src/server/player/context.rs @@ -23,7 +23,10 @@ pub struct ClientContext { state: RwLock, packet_buffer: Mutex>, read_loop: AtomicBool, - is_alive: AtomicBool + is_alive: AtomicBool, + position: RwLock<(f64, f64, f64)>, + velocity: RwLock<(f64, f64, f64)>, + rotation: RwLock<(f32, f32)>, } // Реализуем сравнение через адрес @@ -54,7 +57,10 @@ impl ClientContext { state: RwLock::new(ConnectionState::Handshake), packet_buffer: Mutex::new(VecDeque::new()), read_loop: AtomicBool::new(false), - is_alive: AtomicBool::new(true) + is_alive: AtomicBool::new(true), + position: RwLock::new((0.0, 0.0, 0.0)), + velocity: RwLock::new((0.0, 0.0, 0.0)), + rotation: RwLock::new((0.0, 0.0)) } } @@ -100,6 +106,30 @@ impl ClientContext { self.state.read().unwrap().clone() } + pub fn set_position(self: &Arc, position: (f64, f64, f64)) { + *self.position.write().unwrap() = position; + } + + pub fn set_velocity(self: &Arc, velocity: (f64, f64, f64)) { + *self.velocity.write().unwrap() = velocity; + } + + pub fn set_rotation(self: &Arc, rotation: (f32, f32)) { + *self.rotation.write().unwrap() = rotation; + } + + pub fn position(self: &Arc) -> (f64, f64, f64) { + self.position.read().unwrap().clone() + } + + pub fn velocity(self: &Arc) -> (f64, f64, f64) { + self.velocity.read().unwrap().clone() + } + + pub fn rotation(self: &Arc) -> (f32, f32) { + self.rotation.read().unwrap().clone() + } + pub fn write_packet(self: &Arc, packet: &Packet) -> Result<(), ServerError> { let state = self.state(); let mut packet = packet.clone(); diff --git a/src/server/protocol/play.rs b/src/server/protocol/play.rs index 105f8f9..47a6413 100644 --- a/src/server/protocol/play.rs +++ b/src/server/protocol/play.rs @@ -1,6 +1,6 @@ use std::{io::Cursor, sync::Arc, thread, time::{Duration, SystemTime, UNIX_EPOCH}}; -use rust_mc_proto::{DataWriter, Packet, read_packet}; +use rust_mc_proto::{read_packet, DataReader, DataWriter, Packet}; use crate::server::{data::{text_component::TextComponent, ReadWriteNBT}, player::context::ClientContext, ServerError}; @@ -241,6 +241,48 @@ pub fn handle_play_state( set_center_chunk(client.clone(), 0, 0)?; send_example_chunk(client.clone(), 0, 0)?; + thread::spawn({ + let client = client.clone(); + + move || -> Result<(), ServerError> { + while client.is_alive() { + let mut packet = client.read_any_packet()?; + + match packet.id() { + serverbound::play::SET_PLAYER_POSITION => { + let x = packet.read_double()?; + let y = packet.read_double()?; + let z = packet.read_double()?; + let _ = packet.read_byte()?; // flags + + client.set_position((x, y, z)); + }, + serverbound::play::SET_PLAYER_POSITION_AND_ROTATION => { + let x = packet.read_double()?; + let y = packet.read_double()?; + let z = packet.read_double()?; + let yaw = packet.read_float()?; + let pitch = packet.read_float()?; + let _ = packet.read_byte()?; // flags + + client.set_position((x, y, z)); + client.set_rotation((yaw, pitch)); + }, + serverbound::play::SET_PLAYER_ROTATION => { + let yaw = packet.read_float()?; + let pitch = packet.read_float()?; + let _ = packet.read_byte()?; // flags + + client.set_rotation((yaw, pitch)); + }, + _ => {} + } + } + + Ok(()) + } + }); + let mut ticks_alive = 0u64; while client.is_alive() { @@ -249,7 +291,12 @@ pub fn handle_play_state( } if ticks_alive % 20 == 0 { // 1 sec timer - // do something + let (x, y, z) = client.position(); + + send_system_message(client.clone(), + TextComponent::rainbow(format!( + "Pos: {} {} {}", x as u64, y as u64, z as u64 + )), false)?; } send_system_message(client.clone(), TextComponent::rainbow(format!("Ticks alive: {}", ticks_alive)), true)?;