From 52d4560bd07bbe85e4a082bf3cc4e2dac3323f97 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 1 Feb 2024 16:00:32 +0100 Subject: [PATCH] refactor net code to use enums --- kubi-server/src/auth.rs | 20 +++--- kubi-server/src/client.rs | 19 +++--- kubi-server/src/world.rs | 28 ++++---- kubi-shared/src/networking/channels.rs | 15 +++-- kubi-shared/src/networking/messages.rs | 88 +++++++++++++++++++------- kubi/src/networking/handshake.rs | 14 ++-- kubi/src/networking/player.rs | 12 ++-- kubi/src/networking/world.rs | 20 +++--- 8 files changed, 132 insertions(+), 84 deletions(-) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 5a40946..e2204ef 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -8,10 +8,10 @@ use kubi_shared::{ ServerToClientMessage, InitData, ClientInitData, - C_CLIENT_HELLO, - }, - client::{Client, ClientId, Username}, - channels::{CHANNEL_AUTH, CHANNEL_SYS_EVT}, + ClientToServerMessageType, + }, + client::{Client, ClientId, Username}, + channels::Channel, }, player::{Player, PLAYER_HEALTH}, transform::Transform, entity::{Entity, Health} @@ -37,7 +37,7 @@ pub fn authenticate_players( let ServerEvent::Receive(client_addr, data) = event else{ continue }; - if !event.is_message_of_type::() { + if !event.is_message_of_type::<{ClientToServerMessageType::ClientHello as u8}>() { continue } let Some(client) = server.0.client(client_addr) else { @@ -62,7 +62,7 @@ pub fn authenticate_players( postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { reason: "Incorrect password".into() }).unwrap().into_boxed_slice(), - CHANNEL_AUTH, + Channel::Auth as usize, SendMode::Reliable ); continue @@ -72,7 +72,7 @@ pub fn authenticate_players( postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { reason: "This server is password protected".into() }).unwrap().into_boxed_slice(), - CHANNEL_AUTH, + Channel::Auth as usize, SendMode::Reliable ); continue @@ -88,7 +88,7 @@ pub fn authenticate_players( postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { reason: "Can't find a free spot for you!".into() }).unwrap().into_boxed_slice(), - CHANNEL_AUTH, + Channel::Auth as usize, SendMode::Reliable ); continue @@ -164,7 +164,7 @@ pub fn authenticate_players( }; other_client.borrow_mut().send( postcard::to_allocvec(&message).unwrap().into_boxed_slice(), - CHANNEL_SYS_EVT, + Channel::SysEvt as usize, SendMode::Reliable ); } @@ -175,7 +175,7 @@ pub fn authenticate_players( postcard::to_allocvec(&ServerToClientMessage::ServerHello { init: init_data }).unwrap().into_boxed_slice(), - CHANNEL_AUTH, + Channel::Auth as usize, SendMode::Reliable ); diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs index d94bcdc..8adc975 100644 --- a/kubi-server/src/client.rs +++ b/kubi-server/src/client.rs @@ -5,14 +5,14 @@ use uflow::SendMode; use std::net::SocketAddr; use kubi_shared::{ networking::{ - client::{ClientIdMap, Client}, - messages::{ClientToServerMessage, ServerToClientMessage, C_POSITION_CHANGED}, - channels::CHANNEL_MOVE + client::{ClientIdMap, Client}, + messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType}, + channels::Channel }, transform::Transform }; use crate::{ - server::{ServerEvents, UdpServer}, + server::{ServerEvents, UdpServer}, util::check_message_auth }; @@ -41,9 +41,10 @@ pub fn sync_client_positions( addrs: View, ) { for event in &events.0 { - let Some(message) = check_message_auth::(&server, event, &clients, &addr_map) else { - continue; - }; + let Some(message) = check_message_auth + ::<{ClientToServerMessageType::PositionChanged as u8}> + (&server, event, &clients, &addr_map) else { continue }; + let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else { unreachable!() }; @@ -71,8 +72,8 @@ pub fn sync_client_positions( position, direction } - ).unwrap().into_boxed_slice(), - CHANNEL_MOVE, + ).unwrap().into_boxed_slice(), + Channel::Move as usize, SendMode::Reliable ); } diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index 43bdc5c..62c0667 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -2,8 +2,8 @@ use shipyard::{Unique, UniqueView, UniqueViewMut, Workload, IntoWorkload, AllSto use glam::IVec3; use hashbrown::HashMap; use kubi_shared::networking::{ - messages::{ClientToServerMessage, ServerToClientMessage, C_CHUNK_SUB_REQUEST, C_QUEUE_BLOCK}, - channels::{CHANNEL_WORLD, CHANNEL_BLOCK}, + messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType}, + channels::Channel, client::Client, }; use uflow::{server::RemoteClient, SendMode}; @@ -45,7 +45,11 @@ pub fn send_chunk_compressed( ser_message.truncate(1); ser_message.append(&mut compressed); let ser_message = ser_message.into_boxed_slice(); - client.borrow_mut().send(ser_message, CHANNEL_WORLD, SendMode::Reliable); + client.borrow_mut().send( + ser_message, + Channel::World as usize, + SendMode::Reliable + ); Ok(()) } @@ -59,9 +63,10 @@ fn process_chunk_requests( clients: View ) { for event in &events.0 { - let Some(message) = check_message_auth::(&server, event, &clients, &addr_map) else { - continue; - }; + let Some(message) = check_message_auth + ::<{ClientToServerMessageType::ChunkSubRequest as u8}> + (&server, event, &clients, &addr_map) else { continue }; + let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else { unreachable!() }; @@ -151,16 +156,17 @@ fn process_block_queue_messages( addrs: View, ) { for event in &events.0 { - let Some(message) = check_message_auth::(&server, event, &clients, &addr_map) else { - continue; - }; + let Some(message) = check_message_auth + ::<{ClientToServerMessageType::QueueBlock as u8}> + (&server, event, &clients, &addr_map) else { continue }; + let ClientToServerMessage::QueueBlock { item } = message.message else { unreachable!() }; //TODO place in our own queue, for now just send to other clients log::info!("Placed block {:?} at {}", item.block_type, item.position); for (other_client, other_client_address) in (&clients, &addrs).iter() { //No need to send the event back if message.client_id == other_client.0 { - continue + continue } //Get client let Some(client) = server.0.client(&other_client_address.0) else { @@ -172,7 +178,7 @@ fn process_block_queue_messages( postcard::to_allocvec( &ServerToClientMessage::QueueBlock { item } ).unwrap().into_boxed_slice(), - CHANNEL_BLOCK, + Channel::Block as usize, SendMode::Reliable, ); } diff --git a/kubi-shared/src/networking/channels.rs b/kubi-shared/src/networking/channels.rs index 57de639..c8f1f53 100644 --- a/kubi-shared/src/networking/channels.rs +++ b/kubi-shared/src/networking/channels.rs @@ -1,6 +1,9 @@ -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; -pub const CHANNEL_SYS_EVT: usize = 5; +#[repr(u8)] +pub enum Channel { + Generic = 0, + Auth = 1, + World = 2, + Block = 3, + Move = 4, + SysEvt = 5, +} diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index f2f4ac0..12020ff 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -5,60 +5,86 @@ use super::client::ClientId; pub const PROTOCOL_ID: u16 = 0; -pub const C_CLIENT_HELLO: u8 = 0; -pub const C_POSITION_CHANGED: u8 = 1; -pub const C_CHUNK_SUB_REQUEST: u8 = 2; -pub const C_CHUNK_UNUBSCRIBE: u8 = 3; -pub const C_QUEUE_BLOCK: u8 = 4; +pub trait ToMessageType { + fn message_type(&self) -> T; +} + +#[repr(u8)] +#[non_exhaustive] +pub enum ClientToServerMessageType { + ClientHello = 0, + PositionChanged = 1, + ChunkSubRequest = 2, + ChunkUnsubscribe = 3, + QueueBlock = 4, +} #[derive(Serialize, Deserialize, Clone)] #[repr(u8)] +#[non_exhaustive] pub enum ClientToServerMessage { ClientHello { username: String, password: Option, - } = C_CLIENT_HELLO, + } = ClientToServerMessageType::ClientHello as u8, PositionChanged { position: Vec3, velocity: Vec3, direction: Quat, - } = C_POSITION_CHANGED, + } = ClientToServerMessageType::PositionChanged as u8, ChunkSubRequest { chunk: IVec3, - } = C_CHUNK_SUB_REQUEST, + } = ClientToServerMessageType::ChunkSubRequest as u8, ChunkUnsubscribe { chunk: IVec3, - } = C_CHUNK_UNUBSCRIBE, + } = ClientToServerMessageType::ChunkUnsubscribe as u8, QueueBlock { item: QueuedBlock - } = C_QUEUE_BLOCK, + } = ClientToServerMessageType::QueueBlock as u8, } -pub const S_SERVER_HELLO: u8 = 0; -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; -pub const S_PLAYER_DISCONNECTED: u8 = 6; +impl ToMessageType for ClientToServerMessage { + fn message_type(&self) -> ClientToServerMessageType { + match self { + ClientToServerMessage::ClientHello { .. } => ClientToServerMessageType::ClientHello, + ClientToServerMessage::PositionChanged { .. } => ClientToServerMessageType::PositionChanged, + ClientToServerMessage::ChunkSubRequest { .. } => ClientToServerMessageType::ChunkSubRequest, + ClientToServerMessage::ChunkUnsubscribe { .. } => ClientToServerMessageType::ChunkUnsubscribe, + ClientToServerMessage::QueueBlock { .. } => ClientToServerMessageType::QueueBlock, + } + } +} + +#[repr(u8)] +#[non_exhaustive] +pub enum ServerToClientMessageType { + ServerHello = 0, + ServerFuckOff = 1, + PlayerPositionChanged = 2, + ChunkResponse = 3, + QueueBlock = 4, + PlayerConnected = 5, + PlayerDisconnected = 6, +} #[serde_with::serde_as] #[derive(Serialize, Deserialize, Clone)] #[repr(u8)] +#[non_exhaustive] pub enum ServerToClientMessage { ServerHello { init: InitData - } = S_SERVER_HELLO, + } = ServerToClientMessageType::ServerHello as u8, ServerFuckOff { reason: String, - } = S_SERVER_FUCK_OFF, + } = ServerToClientMessageType::ServerFuckOff as u8, PlayerPositionChanged { client_id: ClientId, position: Vec3, direction: Quat, - } = S_PLAYER_POSITION_CHANGED, + } = ServerToClientMessageType::PlayerPositionChanged as u8, ///## WARNING: THIS IS COMPRESSED ///MESSAGES OF THIS TYPE ARE FULLY @@ -69,19 +95,33 @@ pub enum ServerToClientMessage { #[serde_as(as = "Box<[[[_; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>")] data: BlockData, queued: Vec, - } = S_CHUNK_RESPONSE, + } = ServerToClientMessageType::ChunkResponse as u8, QueueBlock { item: QueuedBlock - } = S_QUEUE_BLOCK, + } = ServerToClientMessageType::QueueBlock as u8, PlayerConnected { init: ClientInitData - } = S_PLAYER_CONNECTED, + } = ServerToClientMessageType::PlayerConnected as u8, PlayerDisconnected { id: ClientId - } = S_PLAYER_DISCONNECTED, + } = ServerToClientMessageType::PlayerDisconnected as u8, +} + +impl ToMessageType for ServerToClientMessage { + fn message_type(&self) -> ServerToClientMessageType { + match self { + ServerToClientMessage::ServerHello { .. } => ServerToClientMessageType::ServerHello, + ServerToClientMessage::ServerFuckOff { .. } => ServerToClientMessageType::ServerFuckOff, + ServerToClientMessage::PlayerPositionChanged { .. } => ServerToClientMessageType::PlayerPositionChanged, + ServerToClientMessage::ChunkResponse { .. } => ServerToClientMessageType::ChunkResponse, + ServerToClientMessage::QueueBlock { .. } => ServerToClientMessageType::QueueBlock, + ServerToClientMessage::PlayerConnected { .. } => ServerToClientMessageType::PlayerConnected, + ServerToClientMessage::PlayerDisconnected { .. } => ServerToClientMessageType::PlayerDisconnected, + } + } } //--- diff --git a/kubi/src/networking/handshake.rs b/kubi/src/networking/handshake.rs index 5bc918a..681a3cf 100644 --- a/kubi/src/networking/handshake.rs +++ b/kubi/src/networking/handshake.rs @@ -1,11 +1,9 @@ use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut}; use uflow::{client::Event as ClientEvent, SendMode}; -use kubi_shared::{ - networking::{ - messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO}, - state::ClientJoinState, - channels::CHANNEL_AUTH, - }, +use kubi_shared::networking::{ + messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType}, + state::ClientJoinState, + channels::Channel, }; use crate::player::{spawn_local_player_multiplayer, spawn_remote_player_multiplayer}; use super::{UdpClient, NetworkEvent}; @@ -27,7 +25,7 @@ pub fn say_hello( postcard::to_allocvec( &ClientToServerMessage::ClientHello { username, password } ).unwrap().into_boxed_slice(), - CHANNEL_AUTH, + Channel::Auth as usize, SendMode::Reliable ); } @@ -40,7 +38,7 @@ pub fn check_server_hello_response( let ClientEvent::Receive(data) = &event.0 else { return None }; - if !event.is_message_of_type::() { + if !event.is_message_of_type::<{ServerToClientMessageType::ServerHello as u8}>() { return None } let Ok(parsed_message) = postcard::from_bytes(data) else { diff --git a/kubi/src/networking/player.rs b/kubi/src/networking/player.rs index 6d6e43d..8b0b470 100644 --- a/kubi/src/networking/player.rs +++ b/kubi/src/networking/player.rs @@ -4,10 +4,10 @@ use uflow::{SendMode, client::Event as ClientEvent}; use kubi_shared::{ transform::Transform, networking::{ - messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED, S_PLAYER_CONNECTED}, - channels::CHANNEL_MOVE, + messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType}, + channels::Channel, client::ClientIdMap, - }, + }, }; use crate::{ events::player_actions::PlayerActionEvent, @@ -35,7 +35,7 @@ pub fn send_player_movement_events( velocity: Vec3::ZERO, direction: *direction }).unwrap().into_boxed_slice(), - CHANNEL_MOVE, + Channel::Move as usize, SendMode::TimeSensitive ); } @@ -51,7 +51,7 @@ pub fn receive_player_movement_events( continue }; - if !event.is_message_of_type::() { + if !event.is_message_of_type::<{ServerToClientMessageType::PlayerPositionChanged as u8}>() { continue } @@ -83,7 +83,7 @@ pub fn receive_player_connect_events( let ClientEvent::Receive(data) = &event.0 else { return None }; - if !event.is_message_of_type::() { + if !event.is_message_of_type::<{ServerToClientMessageType::PlayerConnected as u8}>() { return None }; let Ok(parsed_message) = postcard::from_bytes(data) else { diff --git a/kubi/src/networking/world.rs b/kubi/src/networking/world.rs index a5e0410..efb2cde 100644 --- a/kubi/src/networking/world.rs +++ b/kubi/src/networking/world.rs @@ -4,9 +4,9 @@ use lz4_flex::decompress_size_prepended; use anyhow::{Result, Context}; use kubi_shared::{ networking::{ - messages::{ClientToServerMessage, ServerToClientMessage, S_CHUNK_RESPONSE, S_QUEUE_BLOCK}, - channels::CHANNEL_BLOCK, - }, + messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType}, + channels::Channel, + }, queue::QueuedBlock }; use crate::{ @@ -31,7 +31,7 @@ pub fn inject_network_responses_into_manager_queue( events: View ) { for event in events.iter() { - if event.is_message_of_type::() { + if event.is_message_of_type::<{ServerToClientMessageType::ChunkResponse as u8}>() { let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() }; let packet = decompress_chunk_packet(data).expect("Chunk decode failed"); let ServerToClientMessage::ChunkResponse { @@ -56,13 +56,13 @@ pub fn send_block_place_events( }; client.0.send( postcard::to_allocvec(&ClientToServerMessage::QueueBlock { - item: QueuedBlock { - position: *position, - block_type: *block, + item: QueuedBlock { + position: *position, + block_type: *block, soft: false } - }).unwrap().into_boxed_slice(), - CHANNEL_BLOCK, + }).unwrap().into_boxed_slice(), + Channel::Block as usize, SendMode::Reliable, ); } @@ -76,7 +76,7 @@ pub fn recv_block_place_events( let ClientEvent::Receive(data) = &event.0 else { continue }; - if !event.is_message_of_type::() { + if !event.is_message_of_type::<{ServerToClientMessageType::QueueBlock as u8}>() { continue } let Ok(parsed_message) = postcard::from_bytes(data) else {