diff --git a/kubi-shared/src/networking/channels.rs b/kubi-shared/src/networking/channels.rs index 170fa68..88ddfc1 100644 --- a/kubi-shared/src/networking/channels.rs +++ b/kubi-shared/src/networking/channels.rs @@ -2,3 +2,4 @@ pub const CHANNEL_GENERIC: usize = 0; pub const CHANNEL_AUTH: usize = 1; pub const CHANNEL_WORLD: usize = 2; pub const CHANNEL_BLOCK: usize = 3; +pub const CHANNEL_MOVE: usize = 4; diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index edd3a93..39ef2ec 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -3,7 +3,8 @@ use serde::{Serialize, Deserialize}; use crate::{chunk::BlockData, queue::QueuedBlock}; use super::client::ClientId; -pub const PROTOCOL_ID: u16 = 0; //protocol id not used yet +//protocol id not used yet +pub const PROTOCOL_ID: u16 = 0; pub const C_CLIENT_HELLO: u8 = 0; pub const C_POSITION_CHANGED: u8 = 1; @@ -39,6 +40,7 @@ pub const S_SERVER_FUCK_OFF: u8 = 1; pub const S_PLAYER_POSITION_CHANGED: u8 = 2; pub const S_CHUNK_RESPONSE: u8 = 3; pub const S_QUEUE_BLOCK: u8 = 4; +pub const S_PLAYER_CONNECTED: u8 = 5; #[derive(Serialize, Deserialize, Clone)] #[repr(u8)] @@ -56,7 +58,7 @@ pub enum ServerToClientMessage { } = S_PLAYER_POSITION_CHANGED, ///## WARNING: THIS IS COMPRESSED ///MESSAGES OF THIS TYPE ARE FULLY - ///COMPRESSED EXCEPT THE FIRST BYTE + ///COMPRESSED ***EXCEPT THE FIRST BYTE*** ///TO REDUCE NETWORK USAGE ChunkResponse { chunk: IVec3, @@ -66,6 +68,9 @@ pub enum ServerToClientMessage { QueueBlock { item: QueuedBlock } = S_QUEUE_BLOCK, + PlayerConnected { + init: UserInitData + } = S_PLAYER_CONNECTED, } //--- diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 80b4cfa..0587656 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,26 +1,29 @@ +use glam::Vec3; use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator}; use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; -use uflow::{client::{Client, Config as ClientConfig, Event as ClientEvent}, EndpointConfig}; +use uflow::{client::{Client, Config as ClientConfig, Event as ClientEvent}, EndpointConfig, SendMode}; use kubi_shared::networking::{ messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO}, state::ClientJoinState, - channels::CHANNEL_AUTH, + channels::{CHANNEL_AUTH, CHANNEL_MOVE}, }; use crate::{ - events::EventComponent, + events::{EventComponent, player_actions::PlayerActionEvent}, control_flow::SetControlFlow, world::tasks::ChunkTaskManager, state::is_ingame_or_loading }; mod world; +mod player; use world::{ inject_network_responses_into_manager_queue, send_block_place_events, recv_block_place_events, }; +use player::send_player_movement_events; #[derive(Unique, Clone, Copy, PartialEq, Eq)] pub enum GameType { @@ -168,7 +171,10 @@ pub fn update_networking() -> Workload { pub fn update_networking_late() -> Workload { ( - send_block_place_events.run_if(is_join_state::<{ClientJoinState::Joined as u8}>), + ( + send_block_place_events, + send_player_movement_events, + ).into_sequential_workload().run_if(is_join_state::<{ClientJoinState::Joined as u8}>), flush_client, ).into_sequential_workload() } diff --git a/kubi/src/networking/player.rs b/kubi/src/networking/player.rs new file mode 100644 index 0000000..b10b63b --- /dev/null +++ b/kubi/src/networking/player.rs @@ -0,0 +1,50 @@ +use glam::Vec3; +use shipyard::{UniqueViewMut, View, IntoIter}; +use uflow::{SendMode, client::Event as ClientEvent}; +use kubi_shared::networking::{ + messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED}, + channels::CHANNEL_MOVE, +}; +use crate::events::player_actions::PlayerActionEvent; +use super::{UdpClient, NetworkEvent}; + +pub fn send_player_movement_events( + actions: View, + mut client: UniqueViewMut, +) { + for event in actions.iter() { + let PlayerActionEvent::PositionChanged { position, direction } = event else { + continue + }; + client.0.send( + postcard::to_allocvec(&ClientToServerMessage::PositionChanged { + position: *position, + velocity: Vec3::ZERO, + direction: *direction + }).unwrap().into_boxed_slice(), + CHANNEL_MOVE, + SendMode::TimeSensitive + ); + } +} + +pub fn receive_player_movement_events( + network_events: View, +) { + for event in network_events.iter() { + let ClientEvent::Receive(data) = &event.0 else { + continue + }; + if !event.is_message_of_type::() { + continue + } + let Ok(parsed_message) = postcard::from_bytes(data) else { + log::error!("Malformed message"); + continue + }; + let ServerToClientMessage::PlayerPositionChanged { + client_id, position, direction + } = parsed_message else { unreachable!() }; + //TODO apply position to local player + } +}