refactor net code to use enums

This commit is contained in:
griffi-gh 2024-02-01 16:00:32 +01:00
parent 63e002364e
commit 52d4560bd0
8 changed files with 132 additions and 84 deletions

View file

@ -8,10 +8,10 @@ use kubi_shared::{
ServerToClientMessage, ServerToClientMessage,
InitData, InitData,
ClientInitData, ClientInitData,
C_CLIENT_HELLO, ClientToServerMessageType,
}, },
client::{Client, ClientId, Username}, client::{Client, ClientId, Username},
channels::{CHANNEL_AUTH, CHANNEL_SYS_EVT}, channels::Channel,
}, },
player::{Player, PLAYER_HEALTH}, player::{Player, PLAYER_HEALTH},
transform::Transform, entity::{Entity, Health} transform::Transform, entity::{Entity, Health}
@ -37,7 +37,7 @@ pub fn authenticate_players(
let ServerEvent::Receive(client_addr, data) = event else{ let ServerEvent::Receive(client_addr, data) = event else{
continue continue
}; };
if !event.is_message_of_type::<C_CLIENT_HELLO>() { if !event.is_message_of_type::<{ClientToServerMessageType::ClientHello as u8}>() {
continue continue
} }
let Some(client) = server.0.client(client_addr) else { let Some(client) = server.0.client(client_addr) else {
@ -62,7 +62,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "Incorrect password".into() reason: "Incorrect password".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -72,7 +72,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "This server is password protected".into() reason: "This server is password protected".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -88,7 +88,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "Can't find a free spot for you!".into() reason: "Can't find a free spot for you!".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -164,7 +164,7 @@ pub fn authenticate_players(
}; };
other_client.borrow_mut().send( other_client.borrow_mut().send(
postcard::to_allocvec(&message).unwrap().into_boxed_slice(), postcard::to_allocvec(&message).unwrap().into_boxed_slice(),
CHANNEL_SYS_EVT, Channel::SysEvt as usize,
SendMode::Reliable SendMode::Reliable
); );
} }
@ -175,7 +175,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerHello { postcard::to_allocvec(&ServerToClientMessage::ServerHello {
init: init_data init: init_data
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );

View file

@ -6,8 +6,8 @@ use std::net::SocketAddr;
use kubi_shared::{ use kubi_shared::{
networking::{ networking::{
client::{ClientIdMap, Client}, client::{ClientIdMap, Client},
messages::{ClientToServerMessage, ServerToClientMessage, C_POSITION_CHANGED}, messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType},
channels::CHANNEL_MOVE channels::Channel
}, },
transform::Transform transform::Transform
}; };
@ -41,9 +41,10 @@ pub fn sync_client_positions(
addrs: View<ClientAddress>, addrs: View<ClientAddress>,
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_POSITION_CHANGED>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::PositionChanged as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else { let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else {
unreachable!() unreachable!()
}; };
@ -72,7 +73,7 @@ pub fn sync_client_positions(
direction direction
} }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_MOVE, Channel::Move as usize,
SendMode::Reliable SendMode::Reliable
); );
} }

View file

@ -2,8 +2,8 @@ use shipyard::{Unique, UniqueView, UniqueViewMut, Workload, IntoWorkload, AllSto
use glam::IVec3; use glam::IVec3;
use hashbrown::HashMap; use hashbrown::HashMap;
use kubi_shared::networking::{ use kubi_shared::networking::{
messages::{ClientToServerMessage, ServerToClientMessage, C_CHUNK_SUB_REQUEST, C_QUEUE_BLOCK}, messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType},
channels::{CHANNEL_WORLD, CHANNEL_BLOCK}, channels::Channel,
client::Client, client::Client,
}; };
use uflow::{server::RemoteClient, SendMode}; use uflow::{server::RemoteClient, SendMode};
@ -45,7 +45,11 @@ pub fn send_chunk_compressed(
ser_message.truncate(1); ser_message.truncate(1);
ser_message.append(&mut compressed); ser_message.append(&mut compressed);
let ser_message = ser_message.into_boxed_slice(); 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(()) Ok(())
} }
@ -59,9 +63,10 @@ fn process_chunk_requests(
clients: View<Client> clients: View<Client>
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_CHUNK_SUB_REQUEST>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::ChunkSubRequest as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else { let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else {
unreachable!() unreachable!()
}; };
@ -151,9 +156,10 @@ fn process_block_queue_messages(
addrs: View<ClientAddress>, addrs: View<ClientAddress>,
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_QUEUE_BLOCK>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::QueueBlock as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::QueueBlock { item } = message.message else { unreachable!() }; let ClientToServerMessage::QueueBlock { item } = message.message else { unreachable!() };
//TODO place in our own queue, for now just send to other clients //TODO place in our own queue, for now just send to other clients
log::info!("Placed block {:?} at {}", item.block_type, item.position); log::info!("Placed block {:?} at {}", item.block_type, item.position);
@ -172,7 +178,7 @@ fn process_block_queue_messages(
postcard::to_allocvec( postcard::to_allocvec(
&ServerToClientMessage::QueueBlock { item } &ServerToClientMessage::QueueBlock { item }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_BLOCK, Channel::Block as usize,
SendMode::Reliable, SendMode::Reliable,
); );
} }

View file

@ -1,6 +1,9 @@
pub const CHANNEL_GENERIC: usize = 0; #[repr(u8)]
pub const CHANNEL_AUTH: usize = 1; pub enum Channel {
pub const CHANNEL_WORLD: usize = 2; Generic = 0,
pub const CHANNEL_BLOCK: usize = 3; Auth = 1,
pub const CHANNEL_MOVE: usize = 4; World = 2,
pub const CHANNEL_SYS_EVT: usize = 5; Block = 3,
Move = 4,
SysEvt = 5,
}

View file

@ -5,60 +5,86 @@ use super::client::ClientId;
pub const PROTOCOL_ID: u16 = 0; pub const PROTOCOL_ID: u16 = 0;
pub const C_CLIENT_HELLO: u8 = 0; pub trait ToMessageType<T> {
pub const C_POSITION_CHANGED: u8 = 1; fn message_type(&self) -> T;
pub const C_CHUNK_SUB_REQUEST: u8 = 2; }
pub const C_CHUNK_UNUBSCRIBE: u8 = 3;
pub const C_QUEUE_BLOCK: u8 = 4; #[repr(u8)]
#[non_exhaustive]
pub enum ClientToServerMessageType {
ClientHello = 0,
PositionChanged = 1,
ChunkSubRequest = 2,
ChunkUnsubscribe = 3,
QueueBlock = 4,
}
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
#[repr(u8)] #[repr(u8)]
#[non_exhaustive]
pub enum ClientToServerMessage { pub enum ClientToServerMessage {
ClientHello { ClientHello {
username: String, username: String,
password: Option<String>, password: Option<String>,
} = C_CLIENT_HELLO, } = ClientToServerMessageType::ClientHello as u8,
PositionChanged { PositionChanged {
position: Vec3, position: Vec3,
velocity: Vec3, velocity: Vec3,
direction: Quat, direction: Quat,
} = C_POSITION_CHANGED, } = ClientToServerMessageType::PositionChanged as u8,
ChunkSubRequest { ChunkSubRequest {
chunk: IVec3, chunk: IVec3,
} = C_CHUNK_SUB_REQUEST, } = ClientToServerMessageType::ChunkSubRequest as u8,
ChunkUnsubscribe { ChunkUnsubscribe {
chunk: IVec3, chunk: IVec3,
} = C_CHUNK_UNUBSCRIBE, } = ClientToServerMessageType::ChunkUnsubscribe as u8,
QueueBlock { QueueBlock {
item: QueuedBlock item: QueuedBlock
} = C_QUEUE_BLOCK, } = ClientToServerMessageType::QueueBlock as u8,
} }
pub const S_SERVER_HELLO: u8 = 0; impl ToMessageType<ClientToServerMessageType> for ClientToServerMessage {
pub const S_SERVER_FUCK_OFF: u8 = 1; fn message_type(&self) -> ClientToServerMessageType {
pub const S_PLAYER_POSITION_CHANGED: u8 = 2; match self {
pub const S_CHUNK_RESPONSE: u8 = 3; ClientToServerMessage::ClientHello { .. } => ClientToServerMessageType::ClientHello,
pub const S_QUEUE_BLOCK: u8 = 4; ClientToServerMessage::PositionChanged { .. } => ClientToServerMessageType::PositionChanged,
pub const S_PLAYER_CONNECTED: u8 = 5; ClientToServerMessage::ChunkSubRequest { .. } => ClientToServerMessageType::ChunkSubRequest,
pub const S_PLAYER_DISCONNECTED: u8 = 6; 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] #[serde_with::serde_as]
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
#[repr(u8)] #[repr(u8)]
#[non_exhaustive]
pub enum ServerToClientMessage { pub enum ServerToClientMessage {
ServerHello { ServerHello {
init: InitData init: InitData
} = S_SERVER_HELLO, } = ServerToClientMessageType::ServerHello as u8,
ServerFuckOff { ServerFuckOff {
reason: String, reason: String,
} = S_SERVER_FUCK_OFF, } = ServerToClientMessageType::ServerFuckOff as u8,
PlayerPositionChanged { PlayerPositionChanged {
client_id: ClientId, client_id: ClientId,
position: Vec3, position: Vec3,
direction: Quat, direction: Quat,
} = S_PLAYER_POSITION_CHANGED, } = ServerToClientMessageType::PlayerPositionChanged as u8,
///## WARNING: THIS IS COMPRESSED ///## WARNING: THIS IS COMPRESSED
///MESSAGES OF THIS TYPE ARE FULLY ///MESSAGES OF THIS TYPE ARE FULLY
@ -69,19 +95,33 @@ pub enum ServerToClientMessage {
#[serde_as(as = "Box<[[[_; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>")] #[serde_as(as = "Box<[[[_; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>")]
data: BlockData, data: BlockData,
queued: Vec<QueuedBlock>, queued: Vec<QueuedBlock>,
} = S_CHUNK_RESPONSE, } = ServerToClientMessageType::ChunkResponse as u8,
QueueBlock { QueueBlock {
item: QueuedBlock item: QueuedBlock
} = S_QUEUE_BLOCK, } = ServerToClientMessageType::QueueBlock as u8,
PlayerConnected { PlayerConnected {
init: ClientInitData init: ClientInitData
} = S_PLAYER_CONNECTED, } = ServerToClientMessageType::PlayerConnected as u8,
PlayerDisconnected { PlayerDisconnected {
id: ClientId id: ClientId
} = S_PLAYER_DISCONNECTED, } = ServerToClientMessageType::PlayerDisconnected as u8,
}
impl ToMessageType<ServerToClientMessageType> 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,
}
}
} }
//--- //---

View file

@ -1,11 +1,9 @@
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut}; use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut};
use uflow::{client::Event as ClientEvent, SendMode}; use uflow::{client::Event as ClientEvent, SendMode};
use kubi_shared::{ use kubi_shared::networking::{
networking::{ messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO}, state::ClientJoinState,
state::ClientJoinState, channels::Channel,
channels::CHANNEL_AUTH,
},
}; };
use crate::player::{spawn_local_player_multiplayer, spawn_remote_player_multiplayer}; use crate::player::{spawn_local_player_multiplayer, spawn_remote_player_multiplayer};
use super::{UdpClient, NetworkEvent}; use super::{UdpClient, NetworkEvent};
@ -27,7 +25,7 @@ pub fn say_hello(
postcard::to_allocvec( postcard::to_allocvec(
&ClientToServerMessage::ClientHello { username, password } &ClientToServerMessage::ClientHello { username, password }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
} }
@ -40,7 +38,7 @@ pub fn check_server_hello_response(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
return None return None
}; };
if !event.is_message_of_type::<S_SERVER_HELLO>() { if !event.is_message_of_type::<{ServerToClientMessageType::ServerHello as u8}>() {
return None return None
} }
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {

View file

@ -4,8 +4,8 @@ use uflow::{SendMode, client::Event as ClientEvent};
use kubi_shared::{ use kubi_shared::{
transform::Transform, transform::Transform,
networking::{ networking::{
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED, S_PLAYER_CONNECTED}, messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
channels::CHANNEL_MOVE, channels::Channel,
client::ClientIdMap, client::ClientIdMap,
}, },
}; };
@ -35,7 +35,7 @@ pub fn send_player_movement_events(
velocity: Vec3::ZERO, velocity: Vec3::ZERO,
direction: *direction direction: *direction
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_MOVE, Channel::Move as usize,
SendMode::TimeSensitive SendMode::TimeSensitive
); );
} }
@ -51,7 +51,7 @@ pub fn receive_player_movement_events(
continue continue
}; };
if !event.is_message_of_type::<S_PLAYER_POSITION_CHANGED>() { if !event.is_message_of_type::<{ServerToClientMessageType::PlayerPositionChanged as u8}>() {
continue continue
} }
@ -83,7 +83,7 @@ pub fn receive_player_connect_events(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
return None return None
}; };
if !event.is_message_of_type::<S_PLAYER_CONNECTED>() { if !event.is_message_of_type::<{ServerToClientMessageType::PlayerConnected as u8}>() {
return None return None
}; };
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {

View file

@ -4,8 +4,8 @@ use lz4_flex::decompress_size_prepended;
use anyhow::{Result, Context}; use anyhow::{Result, Context};
use kubi_shared::{ use kubi_shared::{
networking::{ networking::{
messages::{ClientToServerMessage, ServerToClientMessage, S_CHUNK_RESPONSE, S_QUEUE_BLOCK}, messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
channels::CHANNEL_BLOCK, channels::Channel,
}, },
queue::QueuedBlock queue::QueuedBlock
}; };
@ -31,7 +31,7 @@ pub fn inject_network_responses_into_manager_queue(
events: View<NetworkEvent> events: View<NetworkEvent>
) { ) {
for event in events.iter() { for event in events.iter() {
if event.is_message_of_type::<S_CHUNK_RESPONSE>() { if event.is_message_of_type::<{ServerToClientMessageType::ChunkResponse as u8}>() {
let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() }; let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() };
let packet = decompress_chunk_packet(data).expect("Chunk decode failed"); let packet = decompress_chunk_packet(data).expect("Chunk decode failed");
let ServerToClientMessage::ChunkResponse { let ServerToClientMessage::ChunkResponse {
@ -62,7 +62,7 @@ pub fn send_block_place_events(
soft: false soft: false
} }
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_BLOCK, Channel::Block as usize,
SendMode::Reliable, SendMode::Reliable,
); );
} }
@ -76,7 +76,7 @@ pub fn recv_block_place_events(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
continue continue
}; };
if !event.is_message_of_type::<S_QUEUE_BLOCK>() { if !event.is_message_of_type::<{ServerToClientMessageType::QueueBlock as u8}>() {
continue continue
} }
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {